c ++ STL map :: operator []对要删除的条目完成

Sle*_*lek 4 c++ dictionary stl segmentation-fault electric-fence

std::map<int,int> bar;

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

int main()
{
  bar[0] = foo(0);
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

在使用电栅栏检查内存使用情况时,使用GCC 4.8编译的代码会出现故障.

LD_PRELOAD=libefence.so.0.0 ./a.out
Run Code Online (Sandbox Code Playgroud)

问题来自于编译器生成的代码开始在地图中分配新条目,然后执行foo()以获取要放入的值bar[0].在运行时foo(),条目被破坏,代码最终通过写入未分配的内存结束.

操作的排序方式取决于编译器实现,还是由C++当前标准指定?

zne*_*eak 5

标准(§1.915)指定对二元运算符的两个操作数的求值是无序的(除非在某些特定情况下):

除非另有说明,否则对单个运算符的操作数和单个表达式的子表达式的评估是不确定的.

这意味着它并不要求赋值操作的一方在另一方之前进行求值,事实上,依赖于这些未序列操作的顺序是未定义的行为.

对于函数参数的评估顺序,这通常也是如此.

你需要在两个方面打破你的任务:

int result = foo(0);
bar[0] = result;
Run Code Online (Sandbox Code Playgroud)