c++ - C++ 中 Delete 的行为

标签 c++ delete-operator

我正在编写一些奇怪的代码,对我来说它不是很好的代码。

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

.
.
.
delete []pAdapterInfo;

这里的 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;
        }

我看到的:

  1. 如果我取消对 c'tor 和 d'tor 的注释,测试代码会崩溃(断言失败)
  2. 如果我保留它的评论,则不会失败。

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

/*****************************************************************/
/********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++ 的这个特性。

提前致谢。

星期六

最佳答案

我在这里假设 IP_IP_ADAPTER_INFO 是指 Windows 的 IP_ADAPTER_INFO 结构。即使不是,其要点是相同的:您的代码导致未定义的行为,这是编写它的人的错。 立即修复。

您使用 new 分配了一个 char 数组,但随后释放了该内存,就好像它是一个 IP_ADAPTER_INFO 数组一样。 C++ 不知道你在骗它,所以它会尝试将你的 char 数组视为 IP_ADAPTER_INFO 数组,然后在它发现时可怕地死掉可怕的真相。

现在,这有时有效,因为 VC++ 记录了足够的关于分配内存的信息,delete[] 不关心指针的类型,但这是evil evil wrong bad 非法 get-you-taken-out-back-and-shot 代码

它可能适用于您的特定编译器,但这完全是侥幸。你应该改为:

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

但即便如此,除非您需要在全局范围内保留该结构,这本身就表明设计不当,否则您真的不应该使用 newdelete 在这里。你应该做一些更接近于此的事情:

IP_ADAPTER_INFO adapterInfo;
//DoSomethingToAdapterInfo(&adapterInfo);

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

如果您使用堆分配而不是堆栈分配有一些模糊或独特的原因,那么您这样做可能是合理的——但即便如此,转换 new char[...] PIP_ADAPTER_INFO 是错误的。

关于c++ - C++ 中 Delete 的行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3809740/

相关文章:

c++ - Visual Studio 2010 中未解析的外部符号

c++ - 重载、覆盖和替换新/删除的限制是什么?

c++ - 删除动态 vector 数组

c++ - Delete[]操作符使*.exe触发断点出现未加载的wntdll.pdb

c++ - 其他Boost Thread中的Boost调用方法

C++ - 指针函数参数

c++ - lcov 问题 : weird duplicate constructor marked as not covered & function not marked as covered, 即使其行已被执行

c++ - 对数组的引用参数有什么用?

c++ - C++ 中 "::delete"的用途是什么?

c++ - 继承和派生属性在 C++ 中消失