Speicherlecks in C++ (via new+delete)
Um für eine Anwendung zu haben, die keine memory-leaks, hat die Zahl der neu in ein C++ - Projekt entsprechend der Anzahl der zu löschen?
InformationsquelleAutor joemoe | 2009-08-30
Du musst angemeldet sein, um einen Kommentar abzugeben.
Wenn du meinst, benötigen Sie die gleiche Anzahl von Instanzen von
delete
in Ihrem source-code, wie Sie Instanzen vonnew
, dann nicht. Sie können Objektenew
ed in mehreren Orten, aber alle diese Objektedelete
d der gleichen Zeile code. In der Tat ist dies ein gemeinsames idiom.Intelligente Zeiger, unterschiedlicher Arten, in der Regel nehmen viele verschiedene Objekte
new
ed an vielen Orten in der Benutzer-code unddelete
Sie von einem einzigen Ort in der Bibliothek-code.Bearbeiten
Technisch, jede erfolgreich memory allocation Aufruf muss abgeglichen werden mit einem dellocation rufen, dass das zurückgegebene Zeiger von der ursprünglichen Zuweisung Aufruf.
Meisten
new
Ausdrücke zu einem Anruf an eineoperator new
, die den Speicher reserviert und die Konstrukte, die ein Objekt in den neu zugewiesenen Speicher. Mit einemdelete
Ausdruck, der das Objekt zerstört und bewirkt, dass ein Anruf zu einemoperator delete
dass sollte den zugewiesenen Speicher.Gibt es neue Ausdrücke konstruieren von Objekten in der vor-allokierten Speicher (Platzierung
new
). Diese sollte nicht ergänzt werden durch eine delete-Ausdruck, aber die pre-allocated memory müssen möglicherweise freigegeben ist, in einer Weise, die entspricht der ursprünglichen Zuordnung.InformationsquelleAutor CB Bailey
Wenn du meintest "in der source code", dann Nicht.
Finden Sie diesen code :
1 neue, 1 löschen, ((42 - 1) * 1024) Byte Speicher zugespielt.
Wenn Sie also "new" und "delete-Aufruf zur Laufzeit", dann ja. Jeder Speicher erworben mit neuer haben, freigegeben werden löschen:
Nun bei der Ausführung bekamen wir löschen ausgeführt, die für jede neue ausgeführt <=> keine Lecks.
Oups! Behoben! 🙂
Hervorragendes Beispiel, Klaim
Dein zweites Beispiel noch verliert Speicher, wenn einer der
push_back
s oder einem dernew char[1024]
s wirft.Ja, aber dann ist es...außergewöhnlich 😉 ich würde den Einsatz von smart Pointern in echten code, aber dann wäre es schwerer, um zu zeigen, das löschen, die Frage zu beantworten...
InformationsquelleAutor Klaim
Ja. Jeder neue muss ergänzt werden durch ein löschen.
Aber das löschen ist oft versteckt von Ihnen - zum Beispiel:
Hier gibt es einen neuen, aber das löschen (das geschieht automatisch
am Ende des Blocks) ist versteckt in
der std::auto_ptr Umsetzung.
new
muss mit der Anzahl der Anrufe zudelete
, aber ich bin mir nicht sicher, das ist, was die Frage Fragesteller gemeint, die durch die Anzahl dernew
in einem C++ - Projekt.Nun, Fragen Sie nicht mich - Fragen Sie ruhig!
OK, Punkt getroffen!
InformationsquelleAutor
Gibt es ausgefeilte tools wie Rational ist, Reinigen, um den test auf Speicherlecks n C++ - Programme. Leider ist es im Allgemeinen ein hochgradig nicht-triviales problem zu überprüfen, der code an sich ist frei von Speicherlecks, bevor Sie Laufzeit. Deshalb, halten Sie es einfach, Folgen Sie best practices und test so viel wie möglich in der runtime.
InformationsquelleAutor Alex
Müssen Sie mit einem Aufruf von new mit einem Aufruf zu löschen. Seit C++ ist eine objektorientierte Programmiersprache, erwägen, eine Klasse zu erstellen (im Konstruktor) und zu löschen (im Destruktor) die Variablen deklariert oder verwendet werden, in der Klasse. In der Tat, dass wäre unter den Vorteil der Resource Acquisition Is Initialization oder RAII (kurz) idiom. Wenn Sie nicht das Gefühl, wie die Programmierung selbst können Sie immer Speicher aus der STL.
Ein wichtiger Hinweis: wenn Sie eine variable zuordnen, die mit einer neuen und kann Ihr code eine Ausnahme auslösen, Sie kann Speicherverlust, wenn die Ausnahme nicht abgefangen wird und die variable entsprechend gelöscht.
InformationsquelleAutor Partial
Fragen Sie über die Laufzeit call rechnen (z.B. gezählt, die mit einer Instrumentierung profiler)? Mit genau der gleichen Anzahl Aufrufe der
new
(ohne Platzierung neu) unddelete
Betreiber ist weder eine notwendige noch eine hinreichende Bedingung für leak-free-code:NULL
harmlos ist, so viele Leck-Kostenlose Programme nennendelete
mal mehr alsnew
.delete
so oft wienew
aber manchmal löschtNULL
hat ein Leck. So einige Programme, die nennendelete
mal mehr alsnew
aber manchmal löschenNULL
.new
mehr als oftdelete
hat ein Leck.Überprüfen, dass keine Lecks vorhanden sind, müssen Sie sicherstellen, dass jede Adresse zurückgegeben, die von
new
übergebendelete
, nicht nur überprüfen, dass der Aufruf von count entspricht. Und selbst das ist zu kurz gedacht, da die Adressen erneut verwendet werden, für mehrere Zuweisungen.Auch Programme, die nicht Speicherleck, dass Sie reserviert haben, können noch Leck anderen Ressourcen (wie z.B. OS-Datei-handles).
InformationsquelleAutor bk1e
Nicht genau. Jede zugeordnete Objekte mit dem new-operator muss aufgehoben mit der delete-operator. Seine Ordnung zu haben eine Reihe von Operatoren (new oder delete) in verschiedenen Branchen.
Ich persönlich die Verwendung von boost ist shared_ptr beim schreiben von c++ code.
InformationsquelleAutor Steve Severance
Wenn du auf der Suche nach einer vorläufigen Weise zu erkennen Speicherlecks, zählen neue/löscht überhaupt nicht helfen. Allerdings, wenn Sie MS VC, die Sie verwenden können, CRT-eine sehr einfache, aber nützliche Leckagen-Erkennung für Sie:
Dadurch wird die CRT zu nennen _CrtDumpMemoryLeaks Recht vor CRT entladen wird. Wenn es irgendeine, es wird dump diese auf der Konsole:
Es ist auch eine Technik zu finden, die genaue Stelle des Lecks über die Anzahl von einen block ({342}), aber manchmal ist es einfach genug, um zu wissen, ob es irgendwelche Lecks.
Es ersetzt nicht die Notwendigkeit, in der richtigen Speicher-Leckagen-Erkennung-tools, aber vielleicht begrenzt, die Bedürfnisse von Ihnen.
Ich immer verwenden Sie diese Technik in unit-tests. Erlaubt mir zu erkennen, sehr dumm Speicherverluste sehr früh.
InformationsquelleAutor blinnov.com
Gut, es kann, wenn man genau keine
news
und keinedeletes
, oder wenn Sie andere Klassen, wie zB derstl
, um Speicher zu verwalten für Sie.Müssen Sie mit der Anzahl der Anrufe zu
new
mit der Anzahl der Aufrufedelete
.Mehr als oft nicht, wird es mehr kompliziert, das.
Kannst du das erklären?
[0] = new int; a[1] = new int; for (int i=0;i<2;i++) delete a[i];
Sie müssen also zwei Aufrufe von new und zwei Anrufe zu löschen.
Tut mir Leid, dass ich falsch verstanden, etwas, irgendwo.
InformationsquelleAutor quamrana
Um Speicherverluste zu vermeiden, sollte die Anwendung kostenlos alle die Erinnerung es nutzt nicht mehr , es sei denn es ordnet er während seiner Kündigung. Es gibt keine Vorstellung von Speicherverlust in einem Programm, ohne eine Ereignis-Schleife (weil, gut, Ihre Lebenszeit ist die Kündigung von Anfang an 🙂 ).
Aber das ist für erwachsen, Jungs. Für Sie, ja, jeder neue sollte einen entsprechenden löschen, (das heißt, während der Ausführung eines Programms, nicht in Ihrem source-code!) Produzieren Sie einen guten code, nicht Schießen selbst in den Fuß!
Es ist absolut falsch zu sagen, dass ein Programm ohne eine Ereignis-Schleife hat keine Ahnung von memory-leak. Und es ist falsch zu behaupten, dass memory leaks sind in Ordnung, nur weil der Speicher wird freigegeben, wenn der Prozess beendet ist. Betrachten wir ein Programm, das eine lange iterative Berechnung auf eine gewaltige Datenmenge, wie die Bearbeitung von Videos. Wenn es Lecks Speicher auf jeden video-frame, ist es wahrscheinlich, run out of memory und Abstürzen, lange bevor es fertig ist. Ohne ein event-Schleife.
(1) Sie können aus dem Speicher ohne Speicher-Lecks. (2) "die Zerstörung der Finalisierung" hat nichts mit Erinnerung zu tun undicht, weil, wenn Sie verwenden diese Vorgehensweise, die Sie bereits beteiligt sind, in der new/delete-balancing, auch wenn es ad nichts zu tun mit Undichtigkeiten. (3) Mit einer Konstanten Speicher-Leck ist nicht eine gute Gewohnheit, aber es Situationen, wenn Sie mre wichtige Sachen zu tun als das freigeben von Speicher--zum Beispiel, wenn die app abstürzt. Okay, das ist nicht eine Diskussion, board, halten Sie einfach die Abstimmung ab, Wenn Sie nicht mögen, was ich sagte.
Coufal: Es ist nicht immer so einfach. Einmal habe ich es geschafft, ein Programm zu schreiben, dass gespült seiner letzten Ausgabe-Datei nach 2 Stunden, dann waren 4(!) Stunden löschen Speicher. Gewaltsam beenden mein Programm nach dem Spülen machten es 67% schneller. Ursache war, dass ich die meiste Zeit der zwei Stunden Sortieren von Datensätzen, und die Freigabe war zufällig berührt Speicher als Ergebnis. Cache-Effizienz war im wesentlichen 0%.
InformationsquelleAutor P Shved