c++ STL map::operator[] 对正在删除的条目完成
c++ STL map::operator[] done on an entry being deleted
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 编译的代码在使用电围栏检查内存使用情况时出现段错误。
LD_PRELOAD=libefence.so.0.0 ./a.out
问题来自于编译器生成的代码开始在映射中分配一个新条目,然后执行foo()
以获取要放入bar[0]
的值。 运行 foo()
,条目被销毁,代码最终通过写入未分配的内存结束。
操作的排序方式取决于编译器实现,还是由 C++ 当前标准指定?
标准 (§1.9 15) 指定二元运算符的两个操作数的计算是无序的(除非在某些特定情况下):
Except where noted, evaluations of operands of individual operators
and of subexpressions of individual expressions are unsequenced.
这意味着它不要求赋值操作的一侧先于另一侧求值,事实上,依赖于这些未排序操作的顺序是未定义的行为。
函数参数的计算顺序通常也是如此。
您需要将作业分成两部分:
int result = foo(0);
bar[0] = result;
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 编译的代码在使用电围栏检查内存使用情况时出现段错误。
LD_PRELOAD=libefence.so.0.0 ./a.out
问题来自于编译器生成的代码开始在映射中分配一个新条目,然后执行foo()
以获取要放入bar[0]
的值。 运行 foo()
,条目被销毁,代码最终通过写入未分配的内存结束。
操作的排序方式取决于编译器实现,还是由 C++ 当前标准指定?
标准 (§1.9 15) 指定二元运算符的两个操作数的计算是无序的(除非在某些特定情况下):
Except where noted, evaluations of operands of individual operators and of subexpressions of individual expressions are unsequenced.
这意味着它不要求赋值操作的一侧先于另一侧求值,事实上,依赖于这些未排序操作的顺序是未定义的行为。
函数参数的计算顺序通常也是如此。
您需要将作业分成两部分:
int result = foo(0);
bar[0] = result;