代码之家  ›  专栏  ›  技术社区  ›  Satbir

C++中删除的行为

  •  2
  • Satbir  · 技术社区  · 14 年前

    我正在写一段奇怪的代码,对我来说这段代码不好。

    PIP_ADAPTER_INFO pAdapterInfo=(PIP_ADAPTER_INFO)new  
                                   char[sizeof(IP_IP_ADAPTER_INFO)];
    
    .
    .
    .
    delete []pAdapterInfo;
    

    测试代码。

            class TestClass
            {
    
            public:
            /*  TestClass()
                {
                }
                ~TestClass()
                {
                }*/
    
            public:
                int array[10];
            };
    
            int main (int ac, char **av)
    
            {
                TestClass *myptr=(TestClass*) new char[10];
                delete []myptr;
                return 0;
            }
    

    我看到的是:

    1. 如果我取消注释c'tor和d'tor,测试代码就会崩溃(assert失败)

    即使我看到反汇编,在上面两种情况下也是不同的

    /*****************************************************************/
    /********Compiler provided c'tor and d'tor ***********************/
    /*****************************************************************/
    28:       TestClass *myptr=(TestClass*) new char[10];
    00401268   push        0Ah
    0040126A   call        operator new (004082d0)
    0040126F   add         esp,4
    00401272   mov         dword ptr [ebp-8],eax
    00401275   mov         eax,dword ptr [ebp-8]
    00401278   mov         dword ptr [ebp-4],eax
    29:       delete []myptr;
    0040127B   mov         ecx,dword ptr [ebp-4]
    0040127E   mov         dword ptr [ebp-0Ch],ecx
    00401281   mov         edx,dword ptr [ebp-0Ch]
    00401284   push        edx
    00401285   call        operator delete (004060d0)
    0040128A   add         esp,4
    30:
    /*****************************************************************/
    /********User provided c'tor and d'tor ***********************/
    /*****************************************************************/
    28:       TestClass *myptr=(TestClass*) new char[10];
    
    28:       TestClass *myptr=(TestClass*) new char[10];
    00401278   push        0Ah
    0040127A   call        operator new (004083e0)
    0040127F   add         esp,4
    00401282   mov         dword ptr [ebp-8],eax
    00401285   mov         eax,dword ptr [ebp-8]
    00401288   mov         dword ptr [ebp-4],eax
    29:       delete []myptr;
    0040128B   mov         ecx,dword ptr [ebp-4]
    0040128E   mov         dword ptr [ebp-10h],ecx
    00401291   mov         edx,dword ptr [ebp-10h]
    00401294   mov         dword ptr [ebp-0Ch],edx
    00401297   cmp         dword ptr [ebp-0Ch],0
    0040129B   je          main+4Ch (004012ac)
    0040129D   push        3
    0040129F   mov         ecx,dword ptr [ebp-0Ch]
    004012A2   call        @ILT+0(TestClass::`vector deleting destructor') (00401005)
    004012A7   mov         dword ptr [ebp-14h],eax
    004012AA   jmp         main+53h (004012b3)
    004012AC   mov         dword ptr [ebp-14h],0
    

    请帮助您的专业知识来学习C++的这个特性。

    2 回复  |  直到 10 年前
        1
  •  12
  •   Jonathan Grynspan    14 年前

    IP_IP_ADAPTER_INFO IP_ADAPTER_INFO 结构。即使没有,要点是一样的:你的代码导致了未定义的行为,这是谁写的错。

    您分配了一个 char new ,然后释放内存,就好像它是 IP\适配器\信息 . C++不知道你在说谎,所以它会去尝试对待你的 烧焦 数组作为 阵列,然后当它发现可怕的真相时可怕地死去。

    现在,这个有效 有时 delete[] 不关心指针的类型, 但这是邪恶的邪恶的非法 把你带出去开枪 代码

    它可能在您特定的编译器上工作,但这完全是一种侥幸。你应该做的是:

    PIP_ADAPTER_INFO pAdapterInfo = new IP_ADAPTER_INFO;
    //DoSomethingToAdapterInfo(pAdapterInfo);
    delete pAdapterInfo;
    

    新的 delete

    IP_ADAPTER_INFO adapterInfo;
    //DoSomethingToAdapterInfo(&adapterInfo);
    

    让C++处理分配和删除(在堆栈上)。如果需要返回结构,则返回它而不是指向它的指针(这样调用者就不需要担心内存管理)

    new char[...] PIP_ADAPTER_INFO

        2
  •  4
  •   Prasoon Saurav    14 年前

    $5.3.5/3—“在第二个备选方案中 (删除数组)如果 要删除的对象与 未定义。 73 )"

    所以,你看到的是事实上未定义的行为。

    73) 这意味着不能使用void*类型的指针删除对象,因为没有void类型的对象。