Cast中C++中Delete的行为

Sat*_*bir 2 c++ delete-operator

我正在研究一些奇怪的代码,对我而言,这不是一段很好的代码.

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

.
.
.
delete []pAdapterInfo;
Run Code Online (Sandbox Code Playgroud)

这里PIP_ADAPTER_INFO是指向struct IP_IP_ADAPTER_INFO的指针,IP_IP_ADAPTER_INFO的大小是640.

我期待在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;
        }
Run Code Online (Sandbox Code Playgroud)

我所看到的 :

  1. 如果我取消对c'tor和d'tor的评论,测试代码崩溃(断言失败)
  2. 如果我保持评论没有失败.

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

/*****************************************************************/
/********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
Run Code Online (Sandbox Code Playgroud)

请帮助我学习C++的这一功能.

提前致谢.

星期六

Jon*_*pan 12

我在这里假设IP_IP_ADAPTER_INFO你的意思是Windows的IP_ADAPTER_INFO结构.即使不是,这个的要点是一样的:你的代码导致了未定义的行为,而且是编写它的人的错.立即修复它.

你分配了一个charwith 数组new,但随后释放了那个内存,好像它是一个数组IP_ADAPTER_INFO.C++并不知道你在撒谎,所以它会尝试将你的char数组视为一个IP_ADAPTER_INFO数组,然后当它找到可怕的事实时就会死得很厉害.

现在,这个工作有时是因为VC++记录有关分配的内存足够的信息delete[]并不关心指针的类型,但是这是恶有恶报错误坏非法获取任您取出的背和次代码.

它可能适用于您的特定编译器,但这完全是一个侥幸.你应该这样做:

PIP_ADAPTER_INFO pAdapterInfo = new IP_ADAPTER_INFO;
//DoSomethingToAdapterInfo(pAdapterInfo);
delete pAdapterInfo;
Run Code Online (Sandbox Code Playgroud)

但即便如此,除非你需要抓住这个结构在全球范围内,这本身指向糟糕的设计,你真的不应该使用new,并delete在这里所有.你应该做的更接近这个:

IP_ADAPTER_INFO adapterInfo;
//DoSomethingToAdapterInfo(&adapterInfo);
Run Code Online (Sandbox Code Playgroud)

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

如果有一些模糊的或唯一的原因,你正在使用的堆分配而不是堆栈分配的,那么你可能会这样做有道理的-但即使这样,铸造new char[...]PIP_ADAPTER_INFO是坏的.