C++ kostenlos alle verwendeten Speicher von struct
Kurze Frage; habe ich gegoogelt um und fand einige Antworten schon, aber ich bin ein bisschen paranoid, so will ich, um sicher zu sein.
Betrachten Sie diese situation:
struct CoordLocation
{
float X;
float Y;
float Z;
};
int main()
{
CoordLocation *coord = new CoordLocation();
delete coord;
return 0;
}
Wird der Aufruf von delete auch klar, der Speicher verwendet, die durch die Felder X, Y, Z? Einige Antworten fand ich schon erwähnt, dass ich würde Sie einfach löschen Sie die ZEIGER, nicht die tatsächlich referenzierte Objekt auf diese Weise.
Was ist, wenn...
struct CoordLocation
{
float *X;
float *Y;
float *Z;
};
int main()
{
CoordLocation *coord = new CoordLocation();
delete coord;
return 0;
}
Und was ist, wenn ich manuell den Speicher frei, der für jedes Objekt innerhalb der struct-Konstruktor/Destruktor?
struct CoordLocation
{
CoordLocation()
{
*X = new float;
*Y = new float;
*Z = new float;
}
~CoordLocation()
{
delete X; delete Y; delete Z;
}
float *X;
float *Y;
float *Z;
};
int main()
{
CoordLocation *coord = new CoordLocation();
delete coord;
return 0;
}
Ich bemerkt, dass in einer einfachen situation, wie zum Beispiel:
float *a = new float;
*a = 5.0f;
printf("%f", *a);
delete a;
printf("%f", &a);
printf drucken würde 5.0, so wird die variable hingewiesen, die durch eine nicht genau zerstört.
Also meine Frage ist:
Wie kann ich zuverlässig frei (wie in keine Speicherverluste) ALLE benutzten Speicher der struct in diesem Fall?
struct CoordLocation
{
float X;
float Y;
float Z;
};
int main()
{
CoordLocation *coord = new CoordLocation();
delete coord;
return 0;
}
Dank!
- Ihre zweite
printf
ist ein wenig falsch (format-Identifikator nicht übereinstimmen, argument-Typ). Wussten Sie eigentlich schreiben wollenprintf("%f", *a);
, wie in der erstenprintf
? - Wenn Sie eine aktuelle/moderne compiler, der zuverlässigste Weg, um sicherzustellen, dass die neue'ed Speicher wird korrekt gelöscht, ist die Verwendung eines "smart" Zeiger-Typen zur Verfügung, die in der C++ standard-Bibliothek. std::unique_ptr und std::shared_ptr vollständige Eigentum einer neue ed-Objekt und garantieren, dass das Objekt Sie sind verantwortlich für die nicht zugespielt werden. (Im Idealfall werden Sie nie irgendwelche raw-Zeiger überall in Ihrem code)
- Danke für den Tipp, auf der unique_ptr. Ich arbeite mit Visual C++ 2008, damit der compiler unterstützt nicht das neue standard - (nicht finden können, unique_ptr in den std-namespace). Ich gehe mit der alten Art, zumindest bis später.
- Ja, mein Fehler, auf der 2. printf 🙂
Du musst angemeldet sein, um einen Kommentar abzugeben.
Müssen Sie nur
delete
Speicher reservieren Sie mitnew
.Bist du tatsächlich laufen in undefiniertem Verhalten. Obwohl der Wert noch vorhanden, der Speicher wurde freigegeben und wiederverwendet werden können.
Also Folgendes:
können nicht erstellen Sie ein memory leak, wenn du weglassen, den Destruktor.
Ihre nächste snippet:
kann möglicherweise einen Speicherverlust, aber nicht, wie es ist. Folgendes:
Ihre Dritte Beispiel
nicht erstellen Sie ein memory leak, weil Sie kostenlos alle Speicher, die Sie zuweisen. Wenn Sie wurden für das auslassen der Destruktor oder vergessen zu nennen
delete coord;
Sie, Sie hätten ein memory leak.Ist eine gute Faustregel: rufen Sie
delete
für jedennew
und eindelete[]
für jedennew[]
und du bist sicher.new
wirft exception? Es gibt keine Ausnahme-Handler inmain
soterminate
undabort
wird ausgeführt, und das Programm wird beendet werden, aber vor diesem, gibt es nicht ein Speicher-Leck alsdelete coord;
(und sodelete X;
) nie ausgeführt wird?In diesem Beispiel:
Den Speicher befreit. Es gibt keine Lecks im code. Auf das Beispiel, das Sie Gaben, wo Ihr im struct enthaltenen Zeiger, so lange, wie Sie frei Ihnen im Destruktor(wie in deinem Beispiel), gibt es keine Lecks.
In diesem snippet:
Den Wert
a
bleibt die gleiche nach dem löschen, dadelete
(ing) einen Zeiger wird nur markieren Sie eine Speicher-Adresse als "befreit", wird es nicht ändern Sie dessen Inhalt. Zugriff auf befreite-Zeiger ist Undefiniertes Verhalten.Den Zeiger selbst zugeordnet ist, mit automatic storage duration, es ist nichts frei. Die Struktur ist in die drei Felder, die befreit sind, wenn Sie anrufen
delete
. Sie rufen nurdelete
auf etwas, das zurückgegeben wurdenew
.Beim zuordnen von etwas, das man genügend Speicher, um es zu halten, was bedeutet, dass genug Speicher halten alle seine Felder (und einige Hauswirtschaft-Speicher, ist die Umsetzung spezifischer, aber Sie müssen nicht befürchten, dass). Wenn Sie es löschen Sie kostenlos die gleiche Menge an Speicher, die Sie zugeordnet.
Eine Sache zu beachten, jedoch ist in einem Fall wie diesem (in C++ würden Sie nicht erstellen Sie ein Typ wie dieser, aber das Beispiel ist relevant):
In diesem Fall haben Sie ein Leck. Löschen Sie
f
, die darin besteht, genügend Speicher zum halten einer einzigenchar*
, aber waschar*
Punkte wurde dynamisch zugewiesenen sowie. So, Sie brauchen, um frei zu:Wieder, in C++ würde man wohl nicht entwerfen, eine Art auf diese Weise, statt Begünstigung Typen wie
std::string
und Prinzipien wie RAII, aber das Beispiel ist relevant.