4 Stimmen

Was ist das Ergebnis, wenn ich free mit new oder delete mit malloc verwende?

Ist es ein Compilerfehler oder ein Laufzeitfehler? Der folgende Code kann kompiliert werden!

class Base{
void g();
void h();
};

int main()
{
    Base* p = new Base();
    free(p);
return 0;
}

Es kann jedoch nicht mit einer virtuellen Funktion kompiliert werden, wenn ich die Klasse Base wie folgt deklariere

class Base{
virtual void g();
void h();
};

Der folgende Code kann immer kompiliert werden, unabhängig davon, ob die Funktion virtuell ist oder nicht.

class Base{
void g();
void h();
};

int main()
{
    Base* p = (Base*)malloc(sizeof(Base));
    delete p;
return 0;
}

11voto

Nick Dandoulakis Punkte 41402

Unbestimmtes Ergebnis, außerdem ruft malloc() keine Konstruktoren und free() keine Destruktoren auf.

3voto

Wie der Kommentar sagt - das Ergebnis ist, dass das Verhalten des Programms undefiniert ist.

Wenn Sie "new" mit "free" haben, werden Ihre Destruktoren nicht aufgerufen. Das führt in der Regel zu Speicher- und Ressourcenlecks.

Wenn Sie "malloc" mit "delete" verwenden, erhalten Sie keine Konstruktoraufrufe, so dass Ihre Objekte nicht initialisiert sind. Das kann zu allen möglichen Fehlern führen, z. B. wenn der Destruktor aufgerufen wird.

Wie in dem unten stehenden Kommentar angedeutet, gibt es Dinge in Nicht-POD-Typen (z. B. Klassen, die virtuelle Methoden haben, und Klassen, die virtuelle Vererbung verwenden), die initialisiert werden müssen, auch wenn es nicht sofort offensichtlich ist, dass eine Konstruktorinitialisierung erforderlich ist. Wenn Sie ein Objekt malloc und dann eine virtuelle Methode aufrufen, wird Ihr Programm höchstwahrscheinlich abstürzen.

Wenn alle Ihre Typen POD (Plain Old Data) sind, haben Sie vielleicht Glück, aber das hängt sehr stark von Ihrem Compiler ab - es gibt keine Garantie, dass "malloc" und "new" denselben Heap verwenden, so dass es bei einigen Compilern zu Heap Corruption und Abstürzen kommen kann.

Kurz gesagt: Tun Sie es nicht.

1voto

Adam Rosenfield Punkte 373807

Es ist undefiniertes Verhalten . Das bedeutet, dass alles Mögliche passieren könnte - das Programm könnte erfolgreich sein, es könnte schwer abstürzen, es könnte stillschweigend fehlschlagen und viel später in einem unbeteiligten, unschuldig aussehenden Stück Code abstürzen, oder es könnte sogar Ihre Festplatte löschen.

Alles könnte passieren, da Sie etwas tun, was nach dem C++-Standard nicht erlaubt ist.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X