c++ STL map::operator[] done on an entry being deleted

£可爱£侵袭症+ 提交于 2019-12-23 13:07:24

问题


std::map<int,int> bar;

int foo(int key)
{
  bar.erase(key);
  return 1;
}    

int main()
{
  bar[0] = foo(0);
  return 0;
}

This code compiled with GCC 4.8 segs fault when checking memory usage with electric fence.

LD_PRELOAD=libefence.so.0.0 ./a.out

The problem comes from the fact that the compiler generates a code that starts to allocate a new entry in the map, then executes foo() to get the value to put into bar[0]. While running foo(), the entry gets destroyed and the code finally ends by writing in non-allocated memory.

Does the way the operations are ordered depend on the compiler implementation, or is it specified by the C++ current standard?


回答1:


The standard (§1.9 15) specifies that the evaluation of the two operands to a binary operator is unsequenced (unless in some specific cases):

Except where noted, evaluations of operands of individual operators and of subexpressions of individual expressions are unsequenced.

This means that it does not mandate that one side of the assignment operation is evaluated before the other, and in fact, it is undefined behavior to depend on the order of these unsequenced operations.

This is also generally true for the order of evaluation of function arguments.

You need to break your assignment in two:

int result = foo(0);
bar[0] = result;


来源:https://stackoverflow.com/questions/33131966/c-stl-mapoperator-done-on-an-entry-being-deleted

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!