c++ STL map::operator[]在被删除的项上执行

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

本文关键字:删除 执行 map STL operator c++      更新时间:2023-10-16
std::map<int,int> bar;
int foo(int key)
{
  bar.erase(key);
  return 1;
}    
int main()
{
  bar[0] = foo(0);
  return 0;
}

此代码使用GCC 4.8 segs编译,当使用electric fence检查内存使用情况时出现错误。

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

问题来自于编译器生成的代码,该代码开始在映射中分配一个新条目,然后执行foo()以获得要放入bar[0]的值。当运行foo()时,条目被销毁,代码最终以在非分配内存中写入结束。

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

标准(§1.9 15)规定二元操作符的两个操作数的求值是不排序的(除非在某些特殊情况下):

除特别说明外,单个操作符的操作数求值单个表达式的子表达式的和是未排序的。

这意味着它没有强制要求赋值操作的一端在另一端之前求值,实际上,依赖于这些非排序操作的顺序是未定义的行为。

对于函数参数的求值顺序一般也是如此。

你需要把你的任务分成两部分:

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