【问题标题】:GCC crash in debug mode, runs fine in release mode?GCC 在调试模式下崩溃,在发布模式下运行良好?
【发布时间】:2012-08-10 12:48:07
【问题描述】:

我有一个简单的循环,通过一组基类指针运行:

Object * objects[2];

objects[0] = new GreenObject;
objects[1] = new RedObject;
objects[2] = new BlueObject;


for (int i = 0; i < 3; ++i) {
    cout << i << " ";
    objects[i]->info();
}

在调试模式下,当调用info() 方法时,在输出i 之后,程序在循环的第三次迭代中立即崩溃。在发布模式下不会发生这样的事情,它正在按应有的方式运行。这不是对象的问题,因为即使我使用其他派生类它也会锁定。

Windows 7 64bit 下的 GCC 4.4.0

有什么想法吗?

【问题讨论】:

    标签: c++ debugging gcc crash


    【解决方案1】:

    这是(和for 循环)超出数组末尾:

    objects[2] = new BlueObject;
    

    导致未定义的行为。它在发行版中运行的事实只是(不)幸运。未定义行为的一个子集是它的行为符合您的预期。

    数组索引从0N - 1,其中N 是数组中的元素数。在objects 的情况下,有效索引仅为01。将objects的声明改为:

    Object * objects[3];
    

    【讨论】:

    • 是的,我知道数组比它需要的要短,我的沮丧是它在发布模式下工作。
    • 如果你提到你知道它在问题中有错误,它可能会有所帮助,说 “它正在按应有的方式运行” 意味着你认为代码是正确的。
    • 您的程序的内存布局可能因发布和调试设置而异。正如 hmjd 所说,这是完全未定义的行为。
    【解决方案2】:

    访问objects[2] 是未定义的行为。

    期望编程错误总是导致崩溃或明显的故障是一个常见的错误。

    未定义的行为意味着任何事情都可能发生,包括在某些情况下看似起作用。

    如果您想要可预测、可重复的行为,那么您应该编写正确的代码。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多