zoukankan      html  css  js  c++  java
  • C++中delete[]是如何知道数组大小的

    先看一段代码:

    int main(void)

    {

    int *pI = new int;

    int *pArray = new int[10];

    int size = *(pArray-1);

    delete pI;

    delete [] pArray; // delete是如何知道pArray数组大小的?

    return 0;

    }

     

    看反编译后代码,没能直接找到答案,于是在网上搜索发现这样一篇文章:Mismatching scalar and vector new and delete》。文章中说明了内存布局大概是这样:

    这个结论肯定是正确的,但是我却没能在内存中找到这个记录数组大小的地址。再看反编译代码,例子中分别new了一个对象和一个数组,例子最后使用delete[]分别删除了这两个对象。从C++角度来说,第一个delete是scalar "delete",第二个delete [] 是vector "delete"。这两种delete调用应该不一样才对,但从反编译代码看,两处调用完全相同。

    ; int __cdecl main()

    _main proc near

     

    var_5C= dword ptr -5Ch

    var_58= dword ptr -58h

    p= dword ptr -54h

    var_50= dword ptr -50h

    size= dword ptr -0Ch

    pArray= dword ptr -8

    pI= dword ptr -4

     

    push ebp

    mov ebp, esp

    sub esp, 5Ch

    push ebx

    push esi

    push edi

    push 4 ; size

    call j_??2@YAPAXI@Z ; operator new(uint)

    add esp, 4

    mov [ebp+var_5C], eax

    mov eax, [ebp+var_5C]

    mov [ebp+pI], eax

    nop

    push 28h ; size

    call j_??2@YAPAXI@Z ; operator new(uint)

    add esp, 4

    mov [ebp+var_58], eax

    mov eax, [ebp+var_58]

    mov [ebp+pArray], eax

    nop

    mov eax, [ebp+pArray]

    mov ecx, [eax-4]

    mov [ebp+size], ecx

    nop

    mov eax, [ebp+pI]

    mov [ebp+p], eax

    mov ecx, [ebp+p]

    push ecx ; p

    call j_??3@YAXPAX@Z ; operator delete(void *)

    add esp, 4

    nop

    mov eax, [ebp+pArray]

    mov [ebp+var_50], eax

    mov ecx, [ebp+var_50]

    push ecx ; p

    call j_??3@YAXPAX@Z ; operator delete(void *)

    add esp, 4

    xor eax, eax

    pop edi

    pop esi

    pop ebx

    mov esp, ebp

    pop ebp

    retn

    _main endp

    结论:

    • 通过观察"new"调用了HeapAlloc函数,而这一函数使用可以将内存分配情况用结构体保存起来,"delete"估计就是通过这一结构体得到数组大小的。也就是说C++这一语法特点是借用了HeapAlloc等函数对Windows堆内存的管理方式实现的。

    未知&待研究:

    • scalar "new" 与 vector "delete []"出现不匹配的使用时究竟会不会出现问题
    • 通过反编译验证结论。尤其是"delete []"

  • 相关阅读:
    原创 | 我被面试官给虐懵了,竟然是因为我不懂Spring中的@Configuration
    vavr:让你像写Scala一样写Java
    Java黑科技之源:JVMTI完全解读
    JVM 源码解读之 CMS 何时会进行 Full GC
    MySQL 如何优化大分页查询?
    025:为什么需要将Logger对象声明为private static final类型的
    酷家乐一面二面
    趋势科技面试
    生活就是好好经历,无问西东----三月份总结
    30号快手笔试(三道ac两道半)————-历史上最大的网络失误orz
  • 原文地址:https://www.cnblogs.com/cartler/p/3400610.html
Copyright © 2011-2022 走看看