2012-01-16 68 views
2

我有一个类polymerstatic 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

什么调试说呢?在哪里开始回溯? – pmr 2012-01-16 20:06:38

+0

显示更多代码,尤其是如何定义该变量,或许您忘记将其初始化为0?在调试器中运行该程序,并检查崩溃时发生的情况。 – unwind 2012-01-16 20:07:56

回答

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()); 
+0

我意识到我应该使用矢量而不是数组(但我仍然认为在C而不是C++)。现在我将实现你的想法,使一个既有新增功能又有计数增量的功能。我会阅读更多关于C++容器的内容。谢谢! – 2012-01-16 23:52:54

1

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

1

这可能是由于未初始化的变量。尝试在调试器中单步执行代码或仅打印count的值。

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

1

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

如果更改polymer::countpolymers构造的内部和polymer::countnew polymer()后,你显然跳过指数,这很可能会导致什么你的崩溃进行评估。

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

+0

感谢您的回答。我承认我应该咬紧牙关,使用像vector这样的C++容器,但是我仍然坚持用C语言来思考,并且不太愿意冒险。我没有听说过unique_ptr或其他你提到的ptr类。我会研究这些。 – 2012-01-16 23:56:33

+0

@ColinMatheson:你应该真的咬住那颗子弹。特别是从c样式数组到'std :: vector'的转换非常简单,并且从长远来看可以节省很多调试时间。手动资源管理总是容易出错,并且很难在异常情况下正确执行(尝试编写异常安全代码时,手动管理资源通常会导致代码充斥着'try..catch')。我只能推荐学习如何最大限度地使用C++标准库,使得使用C++编程更加美观。 – Grizzly 2012-01-17 00:56:02

0

最简单的解决将是该任务分为二,因此引入测序

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

的理由是在其他的答案解释。

相关问题