我正在使用SDL中的GUI。我创建了一个slave / master类,它包含一个std ::指向它自己的slave的指针列表,用于在GUI中创建一个层次结构(包含按钮的窗口。按钮标签等等)。它运行良好一段时间,直到我编辑了一个完全不同的类,它不会直接影响slave / master类。现在调用旧的slave / master类中的list.push_front()会在VS C ++ 2008 express中调试时抛出以下错误,但我找不到导致它的原因。
“0x00b6decd中的未处理异常” workbench.exe:0xC0000005:访问 违规阅读地点 0x00000004“。
* workbench.exe是我的项目。 第718行的列表代码中的_Insert方法引发了异常:
_Nodeptr _Newnode = _Buynode(_Pnode, _Prevnode(_Pnode), _Val);
列表在主/从类定义中创建,并且在堆上创建slave / master类以插入另一个主从列表中。当调用push_front()时崩溃的列表为空,但它在层次结构中排在第二位,因此它只运行一次。正如我所说,它之前工作正常,奴隶/主类没有被改变导致错误。 新类也使用列表。 使用多个列表会导致冲突吗?我可能不小心搞砸了堆? 我非常感谢您寻求帮助和提示。
P.S代码现在相当大,所以我猜想最好不要包含它。特别是因为我不确定导致错误的原因。对不起,如果它有点稀缺
更新:我已经用创建迭代器并使用insert()替换了push_front()。结果是在分配list.begin()之后指向“baadf00d”的迭代器。 baadf00d是VS用于未分配任何内容的对象的错误/ NULL指针,据我所知。我想这是列表腐败的另一个迹象?
答案 0 :(得分:3)
通常像0x00000004这样的地址错误表示取消引用NULL指针,例如
struct point {
int x;
int y;
};
struct point *pt = NULL;
printf("%d\n", pt->y);
会产生类似的错误。
对我来说闻不到堆腐败,通常那些错误往往更微妙,我打赌这是一个NULL指针的情况。我会调用堆栈并寻找空指针,可能是你要推送到列表前端或该对象本身的对象的成员。如果您确实认为这是一个堆损坏问题,您可以使用免费的gflags
来启用页面堆等,这样可以让您更早地检测到堆损坏,希望它发生时,而不是侧面它后来会产生什么影响。
答案 1 :(得分:0)
可能是您在原始代码中导致某种缓冲区溢出或其他内存损坏,直到现在才显示。不同的列表实例之间不存在冲突的风险,正如您所说,新代码不会与旧代码交互。因此,除了魔法,你已经编码了一个错误。
答案 2 :(得分:0)
鉴于缺乏代码,我能做的最好的事情就是给你一些我能想到的场景:
最明显,也是最难找到的是内存损坏。列表已经开始,因此添加到项目意味着列表操纵废话记忆。 您可以通过在声明中移动变量并更改赋值顺序来测试它。如果这使得错误消失或移动,您正在查看内存问题。您也可以尝试将列表更改为矢量,然后查看它的作用。
第二种可能性是你有一个指针/引用列表,并且这些项在被放入堆栈之前/之后被释放。如果将堆栈对象的地址放入其他位置分配的列表中,则很容易发生这种情况。你说你在堆上创建了对象,所以我猜它不是这个。
答案 3 :(得分:0)
我的猜测,基于看到_Prevnode和push_front的组合是列表先前已损坏,可能是因为滥用了迭代器。另一种破坏列表的方法是从空列表中删除一个元素。确保在VS2008中打开了迭代器调试。它很早就会遇到很多问题。
答案 4 :(得分:0)
最后看完每个角落后,我发现了这个虫子!这完全出乎意料,我觉得有点尴尬。
我最近重新安排了文件。在此之前,我在一个文件夹中有通用类,在子文件夹中有我的用户界面文件。我将GUI文件复制到主文件夹,我认为我已经正确地连接了所有内容,但显然我错过了一个行,当它开始表现时我从未想过。我的库已编译,因为链接很好,但我的测试程序不是......它只是查看旧的头文件!工作得很好,因为标题是相同的,但后来我编辑了一个,并在其中声明的类开始表现得很有趣,显然,因为它无法识别该死的东西了。它看起来像腐败的记忆,所以这就是我所寻找的。 p>
获得的经验:不要让两个版本彼此靠近或根本不相同。