Mögliche memory leak mit C++ - string
Betrachten Sie das folgende C++ - Programm:
#include <cstdlib> //for exit(3)
#include <string>
#include <iostream>
using namespace std;
void die()
{
exit(0);
}
int main()
{
string s("Hello, World!");
cout << s << endl;
die();
}
Läuft dieser durch valgrind zeigt (einige Ausgabe gekürzt aus Platzgründen):
==1643== HEAP SUMMARY:
==1643== in use at exit: 26 bytes in 1 blocks
==1643== total heap usage: 1 allocs, 0 frees, 26 bytes allocated
==1643==
==1643== LEAK SUMMARY:
==1643== definitely lost: 0 bytes in 0 blocks
==1643== indirectly lost: 0 bytes in 0 blocks
==1643== possibly lost: 26 bytes in 1 blocks
==1643== still reachable: 0 bytes in 0 blocks
==1643== suppressed: 0 bytes in 0 blocks
Wie Sie sehen können, gibt es eine Möglichkeit, dass 26 bytes reserviert auf dem heap waren verloren. Ich weiß, dass die std::string
Klasse hat ein 12-byte-struct (zumindest auf meinem 32-bit x86 Architektur-und GNU-compiler 4.2.4), und "Hallo, Welt!" mit einem null-terminator 14 bytes. Wenn ich es richtig verstanden habe, die 12-byte-Struktur enthält einen Zeiger auf die Zeichenkette, die zugewiesene Größe, und die Referenz-Zählung (jemand korrigiert mich wenn ich hier falsch).
Nun meine Fragen: Wie sind C++ - strings gespeichert, die mit Rücksicht auf den stack/heap? Funktioniert ein stack-Objekt existiert für eine std::string
(oder andere STL-Container) wenn deklariert?
P. S. ich hab irgendwo gelesen, dass valgrind kann Bericht ein false positive ist ein Speicherleck in einige C++ - Programme, die mit STL-Containern (und "fast-Container" wie std::string
). Ich bin nicht allzu besorgt über das Leck, aber es tut, wecken meine Neugier in Bezug auf STL-Container und Speicher-management.
- Warum fordern Sie die()?!
- Ich schrieb die
die()
Funktion zum trennen derexit(0)
Anruf vonmain()
. Mein Programm hat jetzt um die Kontrolle zu übertragen, eine Funktion, in der dieexit(0)
Funktion "den Stecker zieht" auf diesem Programm die Ausführung. Bedenken Sie dieses Programm dient keinem nützlichen Zweck für andere als wissenschaftliche Gründe. - Mein Punkt ist, dass die() bewirkt, dass die Lecks in den ersten Platz. Wenn Sie beugte sich auf ein die() drin, zumindest setzen Sie die Zeichenfolge in Ihren eigenen Bereich.
- In anderen Worten, "schoss ich mir selbst in den Fuß und ich ausgetreten." Mein Tipp - verwenden Sie ein tourniquet.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Andere korrekt sind, sind Sie undicht, weil Sie durch den Aufruf von exit. Um klar zu sein, das Leck ist nicht der string zugewiesen, auf den stack-Speicher auf dem heap durch den string. Zum Beispiel:
wird nicht dazu führen valgrind berichten von einem Leck.
Das Leck wahrscheinlich (anstelle von bestimmten), weil Sie einen inneren Zeiger auf reservierten Speicher auf dem heap. basic_string, ist dafür verantwortlich. Aus dem header auf meinem Rechner:
Entscheidend ist, dass _M_p nicht auf den Anfang des reservierten Speicher auf dem heap, es zeigt auf das erste Zeichen in der Zeichenfolge. Hier ist ein einfaches Beispiel:
Dieser Bericht wird wahrscheinlich Leck in valgrind. Wenn Sie kommentieren Sie die Zeilen, in denen ich mich bewege m_data valgrind meldet "still reachable". Wenn Sie die Auskommentierung der Zeile, wo ich m_data auf 0 erhalten Sie eine definitive Auslaufen.
Valgrind Dokumentation mehr Informationen zu wahrscheinlichen Leckagen und inneren Zeiger.
Aufrufen
exit
"beendet das Programm, ohne den aktuellen block und damit ohnezerstören Sie keine Gegenstände, mit automatic storage duration".
In anderen Worten, Leck oder nicht, Sie sollte nicht wirklich interessieren. Wenn Sie anrufen
exit
, du sagst "schließen Sie dieses Programm, ich habe nicht mehr alles egal ist." So stoppen Sie fürsorglich. 🙂Offensichtlich, es geht um Ressourcen, weil Sie nie lassen Sie den Destruktor der string laufen, absolut unabhängig davon, wie es verwaltet die Ressourcen.
exit
Aufruf innerhalb einer Kind-thread, oder nur den thread in dem es aufgerufen wurde ?Natürlich diese "Lecks", durch
exit
ing vors
's stack-frame-Links ist, dass Sie nicht gebens
's Destruktor eine chance zur Ausführung.Als für Ihre Frage wrt
std::string
Lagerung: Verschiedene Implementierungen verschiedene Dinge tun. Einige weisen 12 Byte auf dem stack, der verwendet wird, wenn der string beträgt 12 Byte oder kürzer. Mehr Saiten gehen auf den heap. Andere Implementierungen gehen immer auf den heap. Einige Referenz-gezählt und mit copy-on-write Semantik, einige nicht. Wenden Sie sich bitte an Scott Meyers'Effective STL
, Punkt 15.gcc der STL hat einen eigenen memory-pool für Container und Streicher. Sie können dies ausschalten, schauen Sie in die valgrind-FAQ
http://valgrind.org/docs/manual/faq.html#faq.reports
Ich würde vermeiden, dass über exit() sehe ich keinen wirklichen Grund Sie zu verwenden, anrufen. Nicht sicher, ob es wird dazu führen, den Prozess zu stoppen sofort und ohne Reinigung des Gedächtnisses ersten zwar valgrind tut immer noch erscheinen, zu laufen.