gpt4 book ai didi

C++ 调试断言仅在使用 VPTR 时失败

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:55:16 26 4
gpt4 key购买 nike

我想知道为什么在此处的一种情况下我在 delete 部分得到异常,而在另一种情况下却没有。

没有异常(exception)情况

#include <iostream>
using namespace std;

class A
{
public:
~A() { cout << "A dtor" << endl; }
};

class B : public A
{
public:
int x;
~B() { cout << "B dtor" << endl; }
};


A* f() { return new B; }

int _tmain(int argc, _TCHAR* argv[])
{
cout << sizeof(B) << " " << sizeof(A) << endl;
A* bptr= f();
delete bptr;
}

这里的输出是 4 1 .. A dtor,因为 A 有 1 个字节用于标识,B 有 4 个字节,因为 int x

异常(exception)情况

#include <iostream>
using namespace std;

class A
{
public:
~A() { cout << "A dtor" << endl; }
};

class B : public A
{
public:
virtual ~B() { cout << "B dtor" << endl; }
};


A* f() { return new B; }

int _tmain(int argc, _TCHAR* argv[])
{
cout << sizeof(B) << " " << sizeof(A) << endl;
A* bptr= f();
delete bptr;
}

这里的输出是 4 1 .. A dtor,因为 A 有 1 个字节用于标识,而 B 有 4 个字节,因为它的虚拟析构函数需要 vptr但是 delete 调用 (_BLOCK_TYPE_IS_VALID) 中的调试断言失败。

环境

我正在运行带有 Visual Studio 2010 SP1Rel 的 Windows 7。

最佳答案

参见 this post

快速总结:

  • 你告诉机器删除 A 的一个实例
  • 由于这是我们通过指针/引用调用的类,也许我们应该使用虚拟表 (VT)?
  • A中没有虚拟成员因此没有使用VT
  • 我们调用 A 的标准析构函数……
  • 砰!我们正试图删除 A 类,但碰巧指针引导我们找到 B 的对象,其中包含 A 不知道的 VT。sizeof(A) 为 1(据我所知,大小等于 0 是不合法的)并且sizeof(B) 为 4(由于存在 VT)。我们希望删除 1 个字节,但是有一个 4 字节的 block 。由于DEBUG堆监控,报错被捕获了。

解决方案当然是声明基类的(A)dtorvirtual 所以Bdtor 将始终被调用。

编辑:对于第一种情况,标准是这样说的:

§5.3 In the first alternative (delete object), if the static type of the object to be deleted is different from its dynamic type, the static type shall be a base class of the dynamic type of the object to be deleted and the static type shall have a virtual destructor or the behavior is undefined. In the second alternative (delete array) if the dynamic type of the object to be deleted differs from its static type, the behavior is undefined.

因此,这两种情况都会将我们引向未定义行为的领域,这当然因一种实现而异。但按理说,对于大多数实现而言,第一种情况比第二种情况更容易处理或至少更容易考虑,后者只是一种深奥的反模式。

关于C++ 调试断言仅在使用 VPTR 时失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14910368/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com