Frage

Valgrind meldet einen Speicherverlust, wenn ein Wert in einem String zuweisen.

Ich benutzen den folgenden einfachen Code ein Speicherleck von Valgrind berichtet zu testen.

/******************************************
* FILE: t3.c
* Compiled using : g++ -g t3.c -o t3
*
* $ g++ -v
* Reading specs from /usr/lib/gcc/i686-pc-linux-gnu/3.4.6/specs
* Configured with: ./configure --prefix=/usr --infodir=/share/info --mandir=/share/man
*      --enable-languages=c,c++ --with-system-zlib --program-suffix=-3.4 --enable-threads=posix
* Thread model: posix
* gcc version 3.4.6
 ******************************************/


#include <iostream>
#include <string>

using namespace std;

/**************************************************************
 **************************************************************/
int main(int argc, char *argv[])
{
   string test = "XXXXXXXXX";
   cout << "this is a test " << test << endl;
   exit(0);
}

ich kompilieren mit diesem Befehl:

$ g++ -g t3.c -o t3

Und wenn ich Valgrind führen Sie es meldet einen Speicherverlust, wenn ich versuche, einen Wert in einem String zuweisen. Ich verwende diesen einfachen Test einig Speicherleck in dem realen Programm zu untersuchen, und es scheint, dass String mit irgendeiner Art von Problemen führen kann.

Mit dem 0x8048A6F: main (t3.c: 23) ist die Linie: string test = "XXXXXXXXX"; Kann jemand einen Hinweis auf so seltsame Verhalten geben?

[enzo@P0101222 C]$   valgrind --leak-check=full  ./t3
==3910== Memcheck, a memory error detector.
==3910== Copyright (C) 2002-2007, and GNU GPL'd, by Julian Seward et al.
==3910== Using LibVEX rev 1732, a library for dynamic binary translation.
==3910== Copyright (C) 2004-2007, and GNU GPL'd, by OpenWorks LLP.
==3910== Using valgrind-3.2.3, a dynamic binary instrumentation framework.
==3910== Copyright (C) 2000-2007, and GNU GPL'd, by Julian Seward et al.
==3910== For more details, rerun with: -v
==3910==
this is a test XXXXXXXXX
==3910==
==3910== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 25 from 1)
==3910== malloc/free: in use at exit: 102 bytes in 3 blocks.
==3910== malloc/free: 4 allocs, 1 frees, 126 bytes allocated.
==3910== For counts of detected errors, rerun with: -v
==3910== searching for pointers to 3 not-freed blocks.
==3910== checked 194,136 bytes.
==3910==
==3910== 16 bytes in 1 blocks are definitely lost in loss record 1 of 3
==3910==    at 0x4017846: malloc (m_replacemalloc/vg_replace_malloc.c:149)
==3910==    by 0x4018E05: realloc (m_replacemalloc/vg_replace_malloc.c:306)
==3910==    by 0x41B441A: argz_append (in /lib/libc-2.2.5.so)
==3910==    by 0x41593B9: __newlocale (in /lib/libc-2.2.5.so)
==3910==    by 0x40E010B: std::locale::facet::_S_create_c_locale(__locale_struct*&, char const*, __locale_struct*) (c++locale.cc:99)
==3910==    by 0x407EF6F: std::locale::facet::_S_initialize_once() (../../.././libstdc++-v3/src/locale.cc:172)
==3910==    by 0x407EFB4: std::locale::facet::_S_get_c_locale() (../../.././libstdc++-v3/src/locale.cc:185)
==3910==    by 0x407A422: std::ctype<char>::ctype(unsigned short const*, bool, unsigned) (/usr3/BUILD/gcc/gcc-3.4.6/i686-pc-linux-gnu/libstdc++-v3/include/i686-pc-linux-gnu/bits/ctype_noninline.h:104)
==3910==    by 0x40801D5: std::locale::_Impl::_Impl(unsigned) (/usr3/BUILD/gcc/gcc-3.4.6/libstdc++-v3/libsupc++/new:92)
==3910==    by 0x4080EED: std::locale::_S_initialize_once() (/usr3/BUILD/gcc/gcc-3.4.6/libstdc++-v3/libsupc++/new:92)
==3910==    by 0x4080F84: std::locale::_S_initialize() (../../.././libstdc++-v3/src/locale_init.cc:155)
==3910==    by 0x4080FE7: std::locale::locale() (../../.././libstdc++-v3/src/locale_init.cc:102)
==3910==
==3910==
==3910== 22 bytes in 1 blocks are possibly lost in loss record 2 of 3
==3910==    at 0x4017C38: operator new(unsigned) (m_replacemalloc/vg_replace_malloc.c:163)
==3910==    by 0x40BF2C4: std::string::_Rep::_S_create(unsigned, unsigned, std::allocator<char> const&) (/usr3/BUILD/gcc/gcc-3.4.6/i686-pc-linux-gnu/libstdc++-v3/include/ext/new_allocator.h:81)
==3910==    by 0x40C1CE4: char* std::string::_S_construct<char const*>(char const*, char const*, std::allocator<char> const&, std::forward_iterator_tag) (/usr3/BUILD/gcc/gcc-3.4.6/i686-pc-linux-gnu/libstdc++-v3/include/bits/basic_string.tcc:150)
==3910==    by 0x40C1E15: std::string::string(char const*, std::allocator<char> const&) (/usr3/BUILD/gcc/gcc-3.4.6/i686-pc-linux-gnu/libstdc++-v3/include/bits/basic_string.h:1386)
==3910==    **by 0x8048A6F: main (t3.c:23)**
==3910==
==3910== LEAK SUMMARY:
==3910==    definitely lost: 16 bytes in 1 blocks.
==3910==      **possibly lost: 22 bytes in 1 blocks.**
==3910==    still reachable: 64 bytes in 1 blocks.
==3910==         suppressed: 0 bytes in 0 blocks.
==3910== Reachable blocks (those to which a pointer was found) are not shown.
==3910== To see them, rerun with: --leak-check=full --show-reachable=yes
[enzo@P0101222 C]$
War es hilfreich?

Lösung

Weil Sie exit(0) nennen, so dass der Zeichenfolge destructor wird nie aufgerufen. Nur Verwendung return 0.

Um dies näher auszuführen, der Konstruktor von std::string zuordnet Heap-Speicher der Zeichenfolge zu speichern, auf dem destructor angewiesen, dass der Speicher freizugeben. Wenn Sie ein String-Objekt auf dem Stapel deklarieren, wird der Destruktor automatisch aufgerufen werden soll, wenn das String-Objekt des Bereichs geht, wodurch die Speicher zu befreien. Aber exit ist wirklich ein C-Mechanismus; es sofort beendet das Programm ohne Durchführung einer Stapel Abwickeln bedeutet, dass C ++ Destruktoren für lokale Stapelobjekte werden nicht genannt werden.

Andere Tipps

Wenn Sie fünf Saiten zuweisen, erhalten Sie fünf Mal den Speicherverlust, oder ist es immer noch die gleiche Menge? Wenn es die gleiche Menge ist, dann werden Sie wahrscheinlich nicht ein Leck überhaupt haben. Einige Bibliotheken weisen Speicher für die interne Buchhaltung / Effizienz / et cetera, die erst freigegeben bekommt nach valgrind stoppt suchen. Diese abgeholt als Speicherlecks, weil Ihr Programm die Zuordnung verursacht, aber nie eine Freigabe verursacht. Wenn es fünf Mal ist die Menge, dann die Implementierung von String kann defekt sein. Ich stimme mit Charles Salvia obwohl ... versuchen Sie es mit return 0; statt exit(0); und sehen, ob das etwas ändert.

In einem meiner Informatik Klassen wurde uns gesagt, dass Valgrind gibt Informationen über Saiten, dass wir nicht zu kümmern sollte. Hier ist die Unterdrückung Datei, dass sie uns für Streicher gab: https://sites.google.com/site/complingfiles/files/string. supp

Trotz am Ende des Programm mir keine exit(0) mit hatte ähnliches Problem mit falschen Positiven mit std::string. Ich war die Verknüpfung statisch mit libstdc++. Schalt Verknüpfung Option auf gemeinsame und Kompilieren mit GLIBCXX_FORCE_NEW die Warnungen unterdrückt.

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