Behaviour of Delete in C++ on cast
I am working on some strange piece of code ,For me its not good piece of code.
PIP_ADAPTER_INFO pAdapterInfo=(PIP_ADAPTER_INFO)new
char[sizeof(IP_IP_ADAPTER_INFO)];
.
.
.
delete []pAdapterInfo;
Here PIP_ADAPTER_INFO is pointer to struct IP_IP_ADAPTER_INFO , size of IP_IP_ADAPTER_INFO is 640.
I was expecting crash in delete []pAdapterInfo call.But there is no crash.I wrote an small test code.
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;
}
What i see :
- If i un-comment the c'tor and d'tor, test code crashes (assert fails)
- If i keep it commented nothing fails.
Even if i see disassemble , it is different in both case above
/*****************************************************************/
/********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
Please help me with your expertise to learn this feature of C++ .
Thanks in advance.
Sat
I'm assuming here that by IP_IP_ADAPTER_INFO
you mean Windows' IP_ADAPTER_INFO
structure. Even if not, the gist of this is the same: your code is leading to undefined behaviour, and it's the fault of whoever wrote it. Fix it immediately.
You allocated an array of char
with new
, but then free that memory as if it were an array of IP_ADAPTER_INFO
. C++ doesn't know that you're lying to it, so it goes and tries to treat your char
array as an IP_ADAPTER_INFO
array, and then dies horribly when it finds out the awful truth.
Now, this works sometimes because VC++ records enough info about the allocated memory that delete[]
doesn't care about the pointer's type, but this is evil evil wrong bad illegal get-you-taken-out-back-and-shot code.
It may work on your particular compiler, but that's entirely a fluke. You should instead be doing:
PIP_ADAPTER_INFO pAdapterInfo = new IP_ADAPTER_INFO;
//DoSomethingToAdapterInfo(pAdapterInfo);
delete pAdapterInfo;
But even then, unless you need to hold onto that structure in a global scope, which itself points to bad design, you really shouldn't be using new
and delete
here at all. You should be doing something closer to this:
IP_ADAPTER_INFO adapterInfo;
//DoSomethingToAdapterInfo(&adapterInfo);
Letting C++ handle allocation and deletion (on the stack) for you. If you need to return the structure, return it rather than a pointer to it (so your caller doesn't need to worry about memory management.)
If there's some obscure or unique reason why you are using heap allocation instead of stack allocation, then you may be justified in doing so--but even then, casting new char[...]
to PIP_ADAPTER_INFO
is bad.
$5.3.5/3 - "In the second alternative (delete array) if the dynamic type of the object to be deleted differs from its static type, the behavior is undefined.73)"
So, what you are seeing is infact undefined behavior.
73) This implies that an object cannot be deleted using a pointer of type void* because there are no objects of type void.
精彩评论