VSC++,虚拟方法位于错误地址,奇怪的错误
这家伙:
virtual phTreeClass* GetTreeClass() const { return (phTreeClass*)m_entity_class; }
当被调用时,即使在完全重新编译之后,也会因访问冲突而使程序崩溃。所有成员函数和虚拟成员函数都有正确的内存地址(我将鼠标悬停在调试模式下的方法上),但该函数的内存地址错误:0xfffffffc。
一切看起来都很好:“this”指针,并且在该函数调用之前一切都工作正常。这个功能也很老了,我很长时间没有改变它。经过一番工作后,问题突然出现,我全部注释掉以查看正在做什么,但没有成功。
于是我把虚拟的去掉,编译了,运行正常。我添加虚拟,编译,它仍然工作正常!我基本上没有做任何更改,并且记得我之前确实进行了完整的重新编译,但当时仍然有错误。
我无法重现该问题。但现在它又回来了。我没有改变任何东西。删除虚拟可以解决问题。
This guy:
virtual phTreeClass* GetTreeClass() const { return (phTreeClass*)m_entity_class; }
When called, crashed the program with an access violation, even after a full recompile. All member functions and virtual member functions had correct memory addresses (I hovered mouse over the methods in debug mode), but this function had a bad memory address: 0xfffffffc.
Everything looked okay: the 'this' pointer, and everything works fine up until this function call. This function is also pretty old and I didn't change it for a long time. The problem just suddenly popped up after some work, which I commented all out to see what was doing it, without any success.
So I removed the virtual, compiled, and it works fine. I add virtual, compiled, and it still works fine! I basically changed nothing, and remember that I did do a full recompile earlier, and still had the error back then.
I wasn't able to reproduce the problem. But now it is back. I didn't change anything. Removing virtual fixes the problem.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
除非您非常确定自己在做什么,否则永远不要将 C 风格的强制转换与多态类型一起使用。绝大多数的可能性是您将其转换为它不是的类型。如果您的指针没有隐式转换(因为它们转换为基类,这是安全的),那么您就做错了。
Don't ever use C-style casts with polymorphic types unless you're seriously sure of what you're doing. The overwhelming probability is that you cast it to a type that it wasn't. If your pointers don't implicitly cast (because they cast to a base class, which is safe) then you're doing it wrong.
编译器和链接器与其他软件一样都是由人类编写的软件,因此本质上不可能没有错误。
我们偶尔也会遇到此类无法解释的问题和修复。这里有一个神话,一旦修复了构建就删除 ncb 文件。
Compilers and linkers are pieces of software written by human like any other, and thus inherently cannot be error-free..
We occasionally run into such inexplicable issues and fixes too. There's a myth going around here that deleting the ncb file once fixed a build..
鉴于重新编译最初解决了问题,请尝试首先进行完全清理并重建。
如果失败,那么很可能即使您的
this
指针对您来说看起来是正确的,但它实际上已被删除/解构并指向垃圾内存,而该垃圾内存恰好看起来像真正的对象之前有。如果您使用 gdb 进行调试,则对象指针处的第一个字将是 vtable。如果您在该位置执行x/16xw
(例如)内存转储,gdb 会告诉您那里驻留着哪种对象的 vtable。如果它是最父类型,那么该对象肯定已经消失了。或者,如果每次 this 指针都相同,您可以在类析构函数中放置一个断点,条件是
this ==known_addr
。Given that recompiling originally fixed the problem, try doing a full clean and rebuild first.
If that fails, then it looks extremely likely that even though your
this
pointer appears correct to you, it is in fact deleted/deconstructed and pointed at garbage memory that just happens to look like the real object that was there before. If you're using gdb to debug, the first word at the object's pointer will be the vtable. If you do anx/16xw <addr>
(for example) memory dump at that location gdb will tell you what sort of object's vtable resides there. If it's the parent-most type then the object is definitely gone.Alternately if the this pointer isthe same every time you can put a breakpoint in the class destructor with the condition that
this == known_addr
.