调用 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/