我正在编写一些奇怪的代码,对我来说它不是很好的代码。
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;
}
我看到的:
- 如果我取消对 c'tor 和 d'tor 的注释,测试代码会崩溃(断言失败)
- 如果我保留它的评论,则不会失败。
即使我看到 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;
但即便如此,除非您需要在全局范围内保留该结构,这本身就表明设计不当,否则您真的不应该使用 new
和 delete
在这里。你应该做一些更接近于此的事情:
IP_ADAPTER_INFO adapterInfo;
//DoSomethingToAdapterInfo(&adapterInfo);
让 C++ 为您处理分配和删除(在堆栈上)。如果您需要返回结构,请返回它而不是指向它的指针(因此您的调用者无需担心内存管理。)
如果您使用堆分配而不是堆栈分配有一些模糊或独特的原因,那么您这样做可能是合理的——但即便如此,转换 new char[...]
PIP_ADAPTER_INFO
是错误的。
关于c++ - C++ 中 Delete 的行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3809740/