c++ - 当程序集中的 operator delete() 删除 vptr 指针时?

标签 c++ vtable vptr

调用 operator delete() 时删除 vptr。

但是 vptr 指针是隐藏的,我们不必关心它的内存结构(而且每个编译器的工作原理不同。)

我想知道我刚刚创建的对象中的 vptr 何时在汇编中被删除。

这是来自 VS2010 的汇编代码(void operator delete(void * pUserData))

10315980  mov         edi,edi  
10315982  push        ebp  
10315983  mov         ebp,esp  
10315985  push        0FFFFFFFEh  
10315987  push        10350F48h  
1031598C  push        offset _except_handler4 (10319550h)  
10315991  mov         eax,dword ptr fs:[00000000h]  
10315997  push        eax  
10315998  add         esp,0FFFFFFF4h  
1031599B  push        ebx  
1031599C  push        esi  
1031599D  push        edi  
1031599E  mov         eax,dword ptr [___security_cookie (103604BCh)]  
103159A3  xor         dword ptr [ebp-8],eax  
103159A6  xor         eax,ebp  
103159A8  push        eax  
103159A9  lea         eax,[ebp-10h]  
103159AC  mov         dword ptr fs:[00000000h],eax  
    _CrtMemBlockHeader * pHead;

    RTCCALLBACK(_RTC_Free_hook, (pUserData, 0));

    if (pUserData == NULL)
103159B2  cmp         dword ptr [ebp+8],0  
103159B6  jne         operator delete+3Dh (103159BDh)  
        return;
103159B8  jmp         $LN10 (10315A55h)  

    _mlock(_HEAP_LOCK);  /* block other threads */
103159BD  push        4  
103159BF  call        _lock (102496F0h)  
103159C4  add         esp,4  
    __TRY
103159C7  mov         dword ptr [ebp-4],0  

        /* get a pointer to memory block header */
        pHead = pHdr(pUserData);
103159CE  mov         eax,dword ptr [ebp+8]  
103159D1  sub         eax,20h  
103159D4  mov         dword ptr [ebp-1Ch],eax  

         /* verify block type */
        _ASSERTE(_BLOCK_TYPE_IS_VALID(pHead->nBlockUse));
103159D7  mov         ecx,dword ptr [ebp-1Ch]  
103159DA  mov         edx,dword ptr [ecx+14h]  
103159DD  and         edx,0FFFFh  
103159E3  cmp         edx,4  
103159E6  je          operator delete+0A9h (10315A29h)  
103159E8  mov         eax,dword ptr [ebp-1Ch]  
103159EB  cmp         dword ptr [eax+14h],1  
103159EF  je          operator delete+0A9h (10315A29h)  
103159F1  mov         ecx,dword ptr [ebp-1Ch]  
103159F4  mov         edx,dword ptr [ecx+14h]  
103159F7  and         edx,0FFFFh  
103159FD  cmp         edx,2  
10315A00  je          operator delete+0A9h (10315A29h)  
10315A02  mov         eax,dword ptr [ebp-1Ch]  
10315A05  cmp         dword ptr [eax+14h],3  
10315A09  je          operator delete+0A9h (10315A29h)  
10315A0B  push        offset string L"_BLOCK_TYPE_IS_VALID"... (1021CD48h)  
10315A10  push        0  
10315A12  push        34h  
10315A14  push        offset string L"f:\\dd\\vctools\\crt_bl"... (1021CCE0h)  
10315A19  push        2  
10315A1B  call        _CrtDbgReportW (103145F0h)  
10315A20  add         esp,14h  
    10315A23  cmp         eax,1  
10315A26  jne         operator delete+0A9h (10315A29h)  
10315A28  int         3  

        _free_dbg( pUserData, pHead->nBlockUse );
10315A29  mov         edx,dword ptr [ebp-1Ch]  
10315A2C  mov         eax,dword ptr [edx+14h]  
10315A2F  push        eax  
10315A30  mov         ecx,dword ptr [ebp+8]  
10315A33  push        ecx  
10315A34  call        _free_dbg (10316920h)  
10315A39  add         esp,8  

    __FINALLY
10315A3C  mov         dword ptr [ebp-4],0FFFFFFFEh  
10315A43  call        $LN7 (10315A4Ah)  
10315A48  jmp         $LN10 (10315A55h)  
        _munlock(_HEAP_LOCK);  /* release other threads */
10315A4A  push        4  
10315A4C  call        _unlock (10249740h)  
10315A51  add         esp,4  
$LN8:
10315A54  ret  
    __END_TRY_FINALLY

    return;

提前致谢。 :)

最佳答案

警告:这是一个实现细节。标准 C++ 没有规定应如何实现虚函数,也不知道什么是 vtable/vptr。

类型的 vtable 具有静态持续时间(意味着它在程序的整个生命周期内都存在)。该类型的每个实例都有一个指向该共享 vtable 的 vptr。所以实例不会删除 vtable,因为它不拥有它。

vptr 的存储(不是它指向的 vtable)是实例的一部分,并随实例一起删除。

在构建/销毁过程中,vptr 被设置为每个正在构建的基类的 vtable。看不到最派生类型是人们警告不要在构造函数中调用虚函数的原因——您可能没有调用您期望调用的函数。

一旦调用了最终的析构函数,vptr 将不可用。

关于c++ - 当程序集中的 operator delete() 删除 vptr 指针时?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8426797/

相关文章:

c++ - 什么是类(class)的 VTT?

c++ - 使用 C++ 的 OpenGL : vtable troubles when passing class array to glTexImage2d

c++ - 如果派生类还具有基类中不存在的虚函数,则创建的 vptr 数

c++ - std::condition_variable 是第一次检查条件,还是必须等待别人通知?

python - 是否可以使用 libclang python 解析没有 header 的 cpp 文件中的函数原型(prototype)

c++ - Vector w/Structure w/char buffer[] 的静态初始化

c++ - 为什么我的 C++ 对象丢失了它的 VPTr

c++ - 如何使用#ifdef 检查是否使用了Xlib?

c++ - 未定义的 vtable 引用

c++ - 使用基类引用而不是指针时出现意外的虚函数分派(dispatch)