我有一个polymer
的课程static int count
。
当我创建一个新的polymer
以添加到指针数组时,我使用count
在数组中找到正确的位置,然后更新构造函数中的count
。在Windows中编译时它起作用了。但是,在Linux(Ubuntu)中进行编译时,除非我从构造函数中删除count
的更新,否则它会崩溃。
Windows和Ubuntu中的工作:
polymerPointer[polymer::count] = new polymer();
polymer::count++;
当构造函数不更新静态变量时(见下文)
polymer::polymer(){
//sets up lots of variables but doesn't update the static member
};
Ubuntu中的崩溃(适用于Windows):
polymerPointer[polymer::count] = new polymer();
构造函数何时更新静态变量(见下文)
polymer::polymer(){
//sets up lots of variables and then updates the static member
count++;
};
我可以重写代码,但我不必记得单独更新变量,这就是我将更新放在构造函数中的原因。关于出了什么问题的任何想法?
答案 0 :(得分:2)
你正在达到未定义的行为。
以下内容:
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());
答案 1 :(得分:1)
编译器可以在polymerPointer[polymer::count]
之前合法地评估new polymer();
,或者按照自己的意愿合法评估polymer::count
。这意味着您不能依赖std::vector<std::unique_ptr<Polymer>>
作为原始值。您必须使用更具确定性的内容,例如{{1}}?
答案 2 :(得分:1)
这可能是由于未初始化的变量。尝试在调试器中单步执行代码,或者只打印出count
的值。
您还可以检查polymerPointer
是否指向已分配的内存(您为存储分配了多少内存,是否足以支持count
的所有值?)。
答案 3 :(得分:1)
您的问题是标准不保证您的语句执行顺序,因此polymerPointer[polymer::count] = new polymer();
可能会在执行polymer::count
之前或之后评估new polymer();
。
如果您更改了polymer::count
构建函数中的polymers
并且polymer::count
之后评估new polymer()
,那么您显然会跳过索引,这可能会导致您的崩溃。
但是你真的有任何迫切的理由在这里使用看起来像c风格的数组,而不是使用std::vector
(不需要额外的count
变量)吗?此外,如果您有选择,那么您真的不应该使用手动内存管理,因此如果您有权访问C ++ 11,std::unique_ptr
或std::shared_ptr
,请使用std::tr1::shared_ptr
或boost::shared_ptr
除此以外。如果你正在使用提升boost::ptr_vector
也是一个选项
答案 4 :(得分:0)
最简单的解决方法是将该分配分成两部分,从而引入排序:
polymer*& insert_point = polymerPointer[polymer::count];
insert_point = new polymer();
其他答案解释了推理。