【问题标题】:Why does my program crash when run fine in the debugger but crash when run without the debugger in VS 2010 C++?为什么我的程序在调试器中运行良好时会崩溃,但在 VS 2010 C++ 中没有调试器时会崩溃?
【发布时间】:2013-12-12 20:18:30
【问题描述】:

所以我正在为大学课程开发一个图形程序。老师有代码,但她是EXE。 该代码有效。如果我在 Visual Studio 中并开始调试代码,它工作正常。该程序通过 std::cout 将指令打印到控制台,然后出现 opengl 窗口,一切正常。 但是,如果我在不调试的情况下按 ctrl+f5 运行,则会打印出指令并出现窗口,但窗口的内容只是纯白色。大约一分钟后,程序崩溃并从窗口弹出一个窗口,说对不起程序崩溃或类似的东西。

如果我进入项目文件夹并进入调试文件夹并单击 .exe,指令会再次打印出来,然后弹出“调试断言失败”,并将其归咎于向量索引超出范围。这将使得除了为什么当我通过 Visual Studio 在调试模式下运行程序时不会发生这种情况?

如果我在 Visual Studio 中并将配置从调试更改为发布,则再次打印说明,这一次弹出显示内存分配错误。它指向这行代码:

Model* mutiplyMatrix(Model model,CMatrix matrix)
{
    Model* m=new Model();
    for(unsigned int i=0;i<model.vectorList.size();i++)
    {
        CVector* v=new CVector();
        v->m=matrix*(*(model.vectorList.at(i)->m));
        v->drawBit=model.vectorList.at(i)->drawBit;
        m->addVectorToList(v);
    }
    return m;
}

确切的行是

CVector* v=new CVector();

所以我的问题是如何获得一个我可以给我的老师的 exe。我可以包含所需的库等。问题是该程序有效,但只有当我在调试模式下从 Visual Studio 执行它时。在发布模式下使用或未经调试时,程序会崩溃。

这是视觉工作室 2010。

【问题讨论】:

    标签: c++ visual-studio-2010 visual-studio visual-studio-debugging


    【解决方案1】:

    我听起来很像您正在使用一个未初始化的变量,它会影响循环执行的次数。在调试模式下,由于在调试器下运行的性质,该值可能始终设置为低值或 0。但是,当不在调试器下运行时,您可能会得到一个非常大的值,这反过来又会导致上面的迭代运行很长时间,然后在内存不足时崩溃。我会从model.vectorList.size() 向后追踪,看看价值来自哪里。在您进入打印出大小的 for 循环之前,我还会添加一个 cout 行。

    编辑:

    好吧,我仍然认为您的问题与未初始化变量相关的无限内存分配有关,但是您在代码中执行的许多操作阻碍了您

    Model* mutiplyMatrix(Model mode,CMatrix matrix)
    

    这会触发 Model 和 CMatrix 的副本。如果您的复制构造函数或析构函数设计不正确,那将是有问题的,尤其是在大量使用原始指针成员的情况下。考虑以下类:

    class Foo {
      char * data;
      Foo() { 
        data = new char[1024];
      }
      virtual ~Foo() {
        delete[] data;
      }
    };
    

    看起来不错吧?我分配内存并释放它。但是如果我有一个函数会发生什么

    void bar(Foo foo) {
      std::cout << "Called bar" << std::endl;
    }
    

    如果我用我的 foo 对象之一调用该函数,我会破坏内存。 bar() 接受一个 Foo 对象,而不是一个 Foo 引用,所以我原来的 Foo 在交给bar() 之前被简单地复制了。因为我没有定义拷贝构造函数,所以调用了默认的拷贝构造函数,也就是说只是拷贝了指针值。这意味着当 bar() 结束时,指针将被我的类上的 ~Foo() 析构函数释放。但后来当我原来的 Foo 实例离开范围时,相同的指针将再次被删除。内存损坏和崩溃。

    至少应该声明你的方法

    Model* mutiplyMatrix(Model & mode,CMatrix & matrix)
    

    或者最好是

    Model* mutiplyMatrix(const Model & mode,const CMatrix & matrix)
    

    更糟糕的是,因为我们可以从下面的源代码中推断出 Model 有一个看起来像这样的成员:

    std:list<CVector*> vectorList;
    

    当您的传入模型被复制然后销毁时,它可能会在堆中造成很大的混乱。

    我最大的建议是停止使用这么多该死的指针。

    【讨论】:

    • 听起来不错,尝试在故障线上放置一个断点并查看是否所有对象的所有字段都已初始化。还要检查 CVector 的构造函数的代码,因为它可能有问题。
    • 所以我通过调试器运行它并且调试器找不到。即使分配了内存,调试器也会说 v 不是变量
    • 'v' 不是重要的部分。 CVector 构造函数和 model.vectorList.size() 值是您的嫌疑人。跟踪设置 vectorList.size() 值的内容,并尝试将该大小发送到输出,以便在应用程序崩溃之前查看它是什么。如果调试器让您失败,您需要借助控制台输出和日志文件来告诉您应用程序的进展情况以及任何时候的内部状态。开始添加日志记录。
    • model.vectorList.size() 是 603。它要么运行一次,然后在尝试创建新的 CVector 时崩溃,要么运行 6 次,在第 7 次它在 addVectorToList 上崩溃,内容这是'vectorList.push_back(c);'
    猜你喜欢
    • 2015-03-31
    • 2016-04-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多