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:

  1. Wenn ich un-Kommentar des c'tor und d'tor, Test-Code abstürzt (Assertion fehlschlägt)
  2. 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

War es hilfreich?

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.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top