在函数调用中更新静态成员会导致崩溃

我有一个static int countpolymer 。 当我创build一个新的polymer添加到指针数组我正在使用count来查找数组中的正确位置,然后我更新构造函数中的count 。 而在Windows编译它的工作。 但是,在Linux(Ubuntu)编译时,它会崩溃,除非我从构造函数中删除count的更新。

在Windows和Ubuntu工作:

 polymerPointer[polymer::count] = new polymer(); polymer::count++; 

当构造函数不更新静态variables(见下文)

 polymer::polymer(){ //sets up lots of variables but doesn't update the static member }; 

Ubuntu中的崩溃(在Windows中工作):

 polymerPointer[polymer::count] = new polymer(); 

当构造函数更新静态variables(见下文)

 polymer::polymer(){ //sets up lots of variables and then updates the static member count++; }; 

我可以重写代码,但我喜欢不必记得更新variables分开,这就是为什么我把更新在构造函数。 任何想法出了什么问题?

你正在打击未定义的行为。

下列:

 polymerPointer[polymer::count] = new polymer(); polymer::count++; 

不等于

 polymerPointer[polymer::count] = new polymer(); 

polymer()增加polymer::count

未定义的行为是因为您正在修改一个值并在同一个语句中使用该值:

§1.9p15如果对标量对象的副作用不是相对于同一个标量对象的另一个副作用或者是使用相同标量对象的值进行值计算,那么行为是不确定的。

可能发生的是计数递增,然后对象被放置在数组中的新位置。 现在代码将访问剩下的空白点,就像它保存了一个有效的指针一样,或者当你到达一个数组的末尾时,你可能会尝试将指针放在数组的边界之外。

将计数增量放在与实际插入数组的地方不同的地方是不好的设计。 你应该做的是写一个静态成员函数,添加元素到数组并更新计数,然后使用它而不是手动创建对象并手动将其放入数组中,同时期望计数自动更新。

 class polymer { static void create_new_polymer() { polymerPointer[polymer::count] = new polymer(); count++; } }; 

更好的办法是只使用一个vector ,并管理它自己的数量:

 polymerPointer.push_back(new polymer()); 

编译器可以在new polymer();之前合法地评估polymerPointer[polymer::count] new polymer(); 或者其他方式,如其所愿。 这意味着你不能依靠polymer::count作为原始值。 你必须使用更确定的东西,如std::vector<std::unique_ptr<Polymer>>

这可能是由于一个未初始化的变量。 尝试在调试器中单步执行代码,或者只是输出count的值。

您还可以检查polymerPointer指向已分配的内存(您为存储分配了多少内存,是否足以满足count所有值?)。

你的问题是标准并不能保证你的语句执行的顺序,所以polymerPointer[polymer::count] = new polymer(); 可以在new polymer();之前或之后评估polymer::count new polymer(); 被执行。

如果改变polymers构造函数中的polymer::count并且polymer::countnew polymer()之后被评估,那么显然会跳过指数,这可能是导致碰撞的原因。

但是,你真的有任何迫切的理由使用看起来像一个c风格的数组,而不是使用std::vector (这将不需要额外的count变量)? 此外,如果你有选择,你真的不应该使用手动内存管理,所以使用std::unique_ptrstd::shared_ptr如果你有权访问C ++ 11, std::tr1::shared_ptrboost::shared_ptr 。 如果你使用boost boost::ptr_vector也是一个选项

最简单的解决办法是将这个任务分成两部分,从而引入一个排序

 polymer*& insert_point = polymerPointer[polymer::count]; insert_point = new polymer(); 

其他的答案解释了推理。