当操作符delete()在汇编中删除vptr指针时
When operator delete() in assembly deletes vptr pointer?
当调用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++没有规定虚函数应该如何实现,也不知道虚表/vptr是什么。
类型的虚值表具有静态持续时间(意味着它在程序的整个生命周期中都存在)。该类型的每个实例都有一个到该共享虚函数表的vtr。因此实例不删除虚值表,因为它不拥有它。
vvpr的存储空间(而不是它所指向的虚值表)是实例的一部分,并且随着实例的删除而被删除。
在构造/销毁过程中,在构造每个基类时将vtr设置为实值表。没有看到派生最多的类型是人们警告不要在构造函数中调用虚函数的原因——你可能没有调用你期望调用的函数。
一旦调用了最后的析构函数,vptr就不可用了。
可能在这里:
_free_dbg( pUserData, pHead->nBlockUse );
Vptr是对象的一部分,不能单独删除
相关文章:
- 将数组的地址分配给变量并删除
- 删除一个线程上有数百万个字符串的大型哈希映射会影响另一个线程的性能
- C/C++编译器通常会删除重复的库吗
- 从链接列表c++中删除一个项目
- C++如何通过用户输入删除列表元素
- 为什么在C++中使用私有复制构造函数与删除复制构造函数
- 是否需要删除包含对象的"pair"?
- 如何在自删除后将对象设置为nullptr
- 迭代时从向量和内存中删除对象
- 使用函数"remove"删除重复元素
- 如何从多映射中删除特定的重复项
- 运算符C++ "delete []"仅删除 2 个前值
- 删除指向指针的指针是运行时错误吗
- 将指针设置为"nullptr"并不能防止双重删除?
- 为什么示例代码访问IUnknown中已删除的内存
- 如何通过 getter 函数删除矢量的元素?
- 从控制台中删除最后打印的元素
- C++中的线程安全删除
- 如何从存储在std::映射中的std::集中删除元素
- 当操作符delete()在汇编中删除vptr指针时