C++调试“气味”
我正在调试一个奇怪的问题,其中对象 VMT 突然似乎指向基础对象的方法。
class Base
{
virtual void foo() {}
}
class Derived: public Base
{
void foo() {}
}
Derived * d = new Derived;
... much complex fettling ...
d->foo(); // Help! called Base::foo()!!!
事实证明,“复杂”代码中的一个错误实际上是在执行delete d;
。我不会详细说明,只是说 boost::noncopyable
是您的朋友,并且在任何情况下都不会推出您自己的智能指针类。
但是,我的问题是 - 这种 VMT 的改变是否是您正在处理已删除对象的良好“气味”?我猜想 VMT 在销毁过程中会“展开”回 Base
吗?
显然,这是非常依赖于实现的,我很“幸运”,记忆没有被践踏......
I was debugging an odd problem where an objects VMT suddenly seemed to point to the base object's methods.
class Base
{
virtual void foo() {}
}
class Derived: public Base
{
void foo() {}
}
Derived * d = new Derived;
... much complex fettling ...
d->foo(); // Help! called Base::foo()!!!
It turned that a bug in the 'complex' code was effectively doing delete d;
. I won't go into details except to say that boost::noncopyable
is your friend, and never under ANY circumstances roll your own smart pointer classes.
But, my question is this - is this kind of alteration of the VMT a good 'smell' that you are dealing with a deleted object? I guess that the VMT gets 'unrolled' back to Base
during destruction?
Obviously this is horribly implmentation dependent, and I was 'lucky' that the memory hadn't been trampled on...
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
不确定问题是什么——但我想说的是:
错了:你不幸运——你不幸运。如果在删除过程中内存被践踏,那么代码崩溃可能会更接近实际问题,并且错误会更清晰。
失败的代码应该尽早失败,以便提示失败位置。
Not sure what the question is – but I’d say that this:
is wrong: you weren’t lucky – you were unlucky. Had the memory been trampled on during deletion, you would probably had the code crash much closer to the actual problem and the error would have been much clearer.
Code that fails should fail as early as possible so as to give a hint about the failure location.
我只能代表 g++,您观察到的 vtable 更改实际上就是发生的情况。有时您可以使用它来确定指针的对象已被删除,但这通常没有多大帮助,因为删除可能发生在多个位置。
shared_ptr
和unique_ptr
是管理内存的好朋友。I can only speak for g++, for which the vtable alteration you observed is in fact what happens. You can sometimes use this to determine that a pointer's object was deleted but that doesn't usually help a lot, since deletions may occur in more than one place.
shared_ptr
andunique_ptr
are your friends to manage memory.你很幸运,你得到了基类行为而不是段错误。
如果您正在处理已删除的对象,则行为是未定义的。
You were lucky that you got the base class behavior rather than a segfault.
If you're mucking with a deleted object, the behavior is undefined.