【问题标题】:<list> throws unhandled exception when calling push_front()<list> 在调用 push_front() 时抛出未处理的异常
【发布时间】:2009-07-12 22:35:46
【问题描述】:

我正在开发 SDL 中的 GUI。我创建了一个从/主类,其中包含一个 std::list 指向它自己的从属的指针列表,以在 GUI 中创建一个层次结构(包含按钮的窗口。按钮标签等)。它工作了很长一段时间,直到我编辑了一个完全不同的类,它不会直接影响从属/主类。在 VS C++ 2008 express 中调试时,对旧从属/主类中的 list.push_front() 的调用现在会引发以下错误,我找不到导致它的原因。

"在 0x00b6decd 处未处理的异常 workbench.exe:0xC0000005:访问 违规读取位置 0x00000004。”

*workbench.exe 是我的项目。 在第 718 行的列表代码中的 _Insert 方法中引发了异常:

_Nodeptr _Newnode = _Buynode(_Pnode, _Prevnode(_Pnode), _Val);

列表是在主/从类的定义中创建的,从/主类是在堆上创建的,以插入另一个主从列表中。调用 push_front() 时崩溃的列表是空的,但它在层次结构中排在第二位,所以它工作了一次。正如我所说,它以前工作得很好,并且从属/主类没有被改变导致错误。 新类也使用列表。 使用多个列表会导致冲突吗?我可能不小心搞砸了堆吗? 对我可以寻找的任何帮助和提示表示感谢。

P.S 代码现在相当大,所以我想最好不要包含它。特别是因为我不确定是什么导致了错误。对不起,如果它有点稀缺

更新:我已将 push_front() 替换为创建迭代器并使用 insert()。结果是在分配 list.begin() 后指向“baadf00d”的迭代器。据我所知,baadf00d 是 VS 用来指向尚未分配任何东西的对象的一些错误/NULL 指针。我想这是列表损坏的另一个迹象?

【问题讨论】:

  • 一个非常常见的堆错误是在代码中的其他地方访问超出范围,然后新/删除操作可能会变得很糟糕。我知道这在调试容器类等时发生在我身上。检查你的新类是否有任何超出范围的访问,记住这些可能会发生而不会导致崩溃,它们只是悄悄地发生。

标签: c++ memory list


【解决方案1】:

通常像这样的错误地址为 0x00000004 表示取消引用 NULL 指针,例如

 struct point {
    int x;
    int y;
 };

 struct point *pt = NULL;
 printf("%d\n", pt->y);

会产生这样的错误。

对我来说闻起来不像堆损坏,通常这些错误往往更微妙,我敢打赌这是一个 NULL 指针的情况。我会向上调用堆栈并寻找空指针,可能是您推送到列表前端的对象的成员或该对象本身。如果您确实认为这是一个堆损坏问题,您可以使用免费的gflags 来启用页面堆等,这将让您更早地检测到堆损坏,希望它发生时,而不是通过它的副作用后因。

【讨论】:

    【解决方案2】:

    很可能,您的原始代码中出现了某种缓冲区溢出或其他内存损坏,直到现在才出现。不同列表实例之间没有冲突的风险,正如您所说,新代码不会与旧代码交互。因此,除非有魔法,否则您编写了一个错误。

    【讨论】:

      【解决方案3】:

      鉴于缺乏代码,我能做的最好的就是给你一些我能想到的场景:

      最明显且最难发现的是内存损坏。该列表已被遍历,因此添加到该项目意味着该列表操纵了垃圾内存。 您可以通过在声明中移动变量以及更改赋值顺序来测试这一点。如果这使错误消失或移动,则您正在查看内存问题。您也可以尝试将列表更改为向量,看看会发生什么。

      第二种可能性是您有一个指针/引用列表,并且项目在被放入堆栈之前/之后被释放。如果将堆栈对象的地址放入在别处分配的列表中,这很容易发生。你说你在堆上创建了对象,所以我猜不是这个。

      【讨论】:

        【解决方案4】:

        我的猜测是,基于 _Prevnode 和 push_front 的组合,该列表已被破坏,可能是由于误用了迭代器。另一种破坏列表的方法是从空列表中删除一个元素。确保在 VS2008 中打开了迭代器调试。它会更早发现很多问题。

        【讨论】:

        • 预处理器使用_DEBUG时不是自动开启的吗?我也会仔细检查我的迭代器。
        【解决方案5】:

        在仔细检查了每个角落和缝隙后,我终于找到了这个错误!这完全出乎意料,我对此感到有些尴尬。

        我最近重新安排了文件。在此之前,我在一个文件夹中有通用类,在一个子文件夹中有我的用户界面文件。我将 GUI 文件复制到主文件夹,我认为我将所有内容都正确链接了,但显然我错过了 one 行,并且当它开始起作用时我从未想过。我的库编译后链接得很好,但我的测试程序不是......它只是查看了旧的头文件!因为标题是相同的,所以一开始当然工作得很好,但后来我编辑了一个,并且其中声明的类开始表现得很有趣,显然,因为它无法识别该死的东西了。它看起来像是损坏的内存,所以这就是我要寻找的。​​p>

        经验教训:不要将两个版本放在一起或根本不要放在一起。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2013-07-24
          • 2011-10-10
          • 2013-06-08
          • 1970-01-01
          • 1970-01-01
          • 2012-04-26
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多