Verhalten von Löschen in C ++ auf Guss
-
25-09-2019 - |
Frage
Ich bin auf einige seltsame Stück Code arbeiten, für mich ist es nicht gut Stück Code.
PIP_ADAPTER_INFO pAdapterInfo=(PIP_ADAPTER_INFO)new
char[sizeof(IP_IP_ADAPTER_INFO)];
.
.
.
delete []pAdapterInfo;
Hier PIP_ADAPTER_INFO ist Zeiger auf IP_IP_ADAPTER_INFO struct, Größe IP_IP_ADAPTER_INFO 640 ist.
Ich erwartete Absturz in delete [] pAdapterInfo call.But wird geschrieben kein crash.I eine kleine Testcode.
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;
}
Was ich sehe:
- Wenn ich un-Kommentar des c'tor und d'tor, Test-Code abstürzt (Assertion fehlschlägt)
- Wenn ich halte es kommentiert nichts versagt.
Auch wenn ich auseinanderbauen zu sehen, es ist anders in beiden Fällen über
/*****************************************************************/
/********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
Bitte helfen Sie mir mit Ihrem Know-how dieser Funktion von C ++ zu lernen.
Vielen Dank im Voraus.
Sa
Lösung
Ich gehe davon aus, dass hier durch IP_IP_ADAPTER_INFO
bedeuten Sie Windows' IP_ADAPTER_INFO
Struktur. Selbst wenn nicht, ist der Kern dieses das gleiche: Sie Ihren Code nicht definiertes Verhalten führt, und es ist die Schuld, wer es geschrieben hat. Fix es sofort.
Sie zugewiesen eine Reihe von char
mit new
, aber dann, dass der Speicher freizugeben, als ob es eine Reihe von IP_ADAPTER_INFO
waren. C ++ nicht weiß, dass Sie es lügen, so geht es und versucht Ihre char
Array als IP_ADAPTER_INFO
Array zu behandeln, und dann stirbt schrecklich, wenn es die schreckliche Wahrheit herausfindet.
Nun, das funktioniert, manchmal , weil VC ++ zeichnet genug Informationen über die zugewiesenen Speicher, dass delete[]
nicht über den Zeigertyp schert, , aber das ist böse böse falsch schlecht illegal get -Sie-genommen-out-back-and-shot Code .
Es kann auf Ihrem speziellen Compiler arbeiten, aber das ist ganz ein Zufall. Sie sollten stattdessen tun:
PIP_ADAPTER_INFO pAdapterInfo = new IP_ADAPTER_INFO;
//DoSomethingToAdapterInfo(pAdapterInfo);
delete pAdapterInfo;
Aber auch dann, wenn Sie in einem globalen Umfang auf diese Struktur zu halten brauchen, die sich ihr schlechtes Design zeigen, sollen Sie wirklich hier überhaupt nicht mit new
und delete
sein. Sie sollten etwas näher an das tun:
IP_ADAPTER_INFO adapterInfo;
//DoSomethingToAdapterInfo(&adapterInfo);
Miete C ++ Griff Zuweisung und Löschen (auf dem Stack) für Sie. Wenn Sie die Struktur zurückkommen müssen, bringen Sie es eher als einen Zeiger auf sie (so Ihre Anrufer muss nicht Sorgen um die Speicherverwaltung.)
Wenn es etwas unklar oder einzigartiger Grund ist, warum Du Heapzuordnung statt Stack Zuweisung verwenden, dann können Sie dabei gerechtfertigt sein -. Aber auch dann, Gießen new char[...]
zu PIP_ADAPTER_INFO
ist schlecht
Andere Tipps
5.3.5 / 3 $ - „In der zweiten Alternative (DELETE-Array), wenn die dynamische Art von das Objekt gelöscht werden soll, unterscheidet sich von sein statischer Typ, das Verhalten ist undefined. 73 ) "
Also, was Sie ist infact nicht definiertes Verhalten zu sehen.
73) Dies bedeutet, dass ein Objekt nicht einen Zeiger vom Typ void * gelöscht werden verwendet, weil es keine Objekte vom Typ void sind.