编译器通过基类指针执行delete时,如何向operator delete传递正确对象大小?
基类指针执行delete时,operator delete如何获取正确的对象大小
核心原因在于基类的虚析构函数——当基类声明了虚析构,编译器会通过虚函数机制,在delete基类指针时自动传递派生类对象的真实大小给operator delete。
结合示例代码分析
你给出的代码里,Employee类声明了虚析构函数virtual ~Employee() {},Manager作为派生类继承它并包含64字节的数组。执行Employee* pE = new Manager()时,operator new会接收Manager对象的完整大小(64位系统下,虚表指针占8字节+64字节数组,总共72字节),所以输出operator new 72。
当执行delete pE时:
- 由于
pE指向的是Manager对象,且基类有虚析构,程序会通过对象的虚表指针找到Manager的析构函数,先完成派生类对象的析构。 - 析构完成后,编译器生成的代码会自动将
Manager对象的真实大小(72字节)作为参数传递给operator delete,因此输出operator delete 72,保证内存被正确释放。
底层实现逻辑(编译器层面)
- 带虚函数的对象会包含一个虚表指针,虚表中除了存储虚函数的地址,还会关联对象的大小信息(或者编译器会在虚析构函数的实现中嵌入传递正确大小的逻辑)。
- 若基类没有声明虚析构,
delete基类指针时,编译器只会按照基类的大小调用operator delete,这会导致派生类额外分配的内存无法被释放,引发内存泄漏甚至未定义行为。
内容的提问来源于stack exchange,提问作者sam
相关产品推荐
相关产品推荐

