Valgrind rapports de fuite de mémoire lors de l'affectation d'une valeur à une chaîne
Valgrind signale une fuite de mémoire lors de l'affectation d'une valeur à une chaîne.
J'ai utilisé le code simple suivant pour tester une fuite de mémoire rapporté par Valgrind.
/******************************************
* 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);
}
Je compiler à l'aide de cette commande:
$ g++ -g t3.c -o t3
Et quand je lance Valgrind il fait état d'une fuite de mémoire lorsque j'essaie d'assigner une valeur à une chaîne. Je suis l'aide de ce test simple pour étudier certains fuite de mémoire dans le programme réel, et il semble que l'aide de la chaîne peut provoquer une sorte de problème.
Par 0x8048A6F: principal (t3.c:23) est la ligne : string test = "XXXXXXXXX";
Quelqu'un peut donner un indice sur cette étrange comportement?
[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]$
Vous devez vous connecter pour publier un commentaire.
Parce que vous appelez
exit(0)
, la chaîne destructeur n'est jamais invoquée. Utilisez simplementreturn 0
.À élaborer, le constructeur de
std::string
alloue de la mémoire dans la mémoire pour stocker la chaîne, en s'appuyant sur le destructeur de désallouer la mémoire. Si vous déclarez un objet de type string sur la pile, le destructeur sera automatiquement appelée lorsque l'objet string est hors de portée, libérant ainsi la mémoire. Maisexit
est vraiment un C mécanisme; il quitte immédiatement le programme sans effectuer de la pile-déroulage sens que C++ destructeurs pour les locaux objets de pile ne sera pas appelé.Si vous allouer cinq cordes, avez-vous cinq fois la fuite de mémoire, ou est-il toujours le même montant? Si c'est le même montant, alors vous n'avez probablement pas une fuite. Certaines bibliothèques allouer de la mémoire pour la comptabilité interne/efficacité/etc que n'est pas libéré jusqu'à ce que après valgrind s'arrête à la recherche. Ces ramassé que des fuites de mémoire parce que votre programme a provoqué l'allocation mais jamais provoqué une libération de la mémoire. Si c'est cinq fois le montant, puis la mise en œuvre de la chaîne peut être en faute. Je suis d'accord avec Charles Salvia mais... essayez de nouveau avec
return 0;
au lieu deexit(0);
et voir si cela change quoi que ce soit.Dans un de mes cours d'informatique nous a dit que Valgrind sorties d'informations sur les chaînes que nous ne devrions pas nous inquiéter. Voici le fichier de suppression qu'ils nous ont donné pour les chaînes:
https://sites.google.com/site/complingfiles/files/string.supp
Malgré avoir aucune
exit(0)
à la fin du programme, j'ai eu le même problème avec des faux positifs avecstd::string
. J'ai été liaison statique aveclibstdc++
. De commutation reliant option de partage et de compiler avecGLIBCXX_FORCE_NEW
supprimé les mises en garde.GLIBCXX_FORCE_NEW
drapeau ne fait pas faire quoi que ce soit. Selon le libstdc++ docs pour mt_allocator, c'est une variable d'environnement. "Si le GLIBCXX_FORCE_NEW variable d'environnement est définie, il définit l'bool _S_force_new de vrai et puis revient.". Donc, il suffit de faire quelque chose commeexport GLIBCXX_FORCE_NEW=1;
puis exécutez valgrind. Cette résolu beaucoup de problèmes que j'ai eu avec std::string donner de faux positifs.