2009-12-14 1 views
10

Valgrind는 값을 문자열에 할당 할 때 메모리 누수를보고합니다.문자열에 값을 할당 할 때 Valgrind에서 메모리 누수를보고합니다.

다음 간단한 코드를 사용하여 Valgrind에서보고 한 메모리 누수를 테스트했습니다.

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

을 내가 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); 
} 

나는이 명령을 사용하여 컴파일합니다. 이 간단한 테스트를 사용하여 실제 프로그램에서 일부 메모리 누수를 조사하고 있는데 문자열을 사용하면 문제가 발생할 수 있습니다.

0x8048A6F 기준 : main (t3.c : 23)은 줄입니다. string test = "XXXXXXXXX"; 누군가 그와 같은 이상한 행동에 대한 힌트를 줄 수 있습니까?

[[email protected] 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 
[[email protected] C]$ 

답변

43

exit(0)을 호출하므로 문자열 소멸자가 호출되지 않습니다. return 0을 사용하십시오.

더 자세히 설명하면 std::string의 생성자는 소멸자를 사용하여 해당 메모리를 할당 해제하기 위해 힙 메모리를 할당하여 문자열을 저장합니다. 스택에 문자열 객체를 선언하면 문자열 객체가 범위를 벗어나 메모리를 해제 할 때 소멸자가 자동으로 호출됩니다. 그러나 exit은 실제로 C 메커니즘입니다. 그것은 스택 스택 해제를 수행하지 않고 즉시 프로그램을 종료합니다. 즉, 로컬 스택 객체에 대한 C++ 소멸자가 호출되지 않습니다.

3

5 개의 문자열을 할당하는 경우 메모리 누수가 5 배가 되는가, 아니면 여전히 같은 양입니까? 같은 양이라면 누출이 전혀 없을 것입니다. 일부 라이브러리는 valgrind가 중지되기 전까지는 공개되지 않는 내부 부기/효율성/등을 위해 메모리를 할당합니다. 프로그램이 할당을 일으켰지 만 할당 해제가 발생하지 않았기 때문에 이것들은 메모리 누수로 선택됩니다. 금액의 5 배인 경우 문자열 구현이 잘못되었을 수 있습니다. 나는 Charles Salvia와 동의합니다 ... 대신에 return 0;으로 다시 시도하고 변경 사항이 있는지 확인하십시오.

3

컴퓨터 과학 수업 중 하나에서 우리는 Valgrind가 우리가 걱정해서는 안되는 문자열에 대한 정보를 출력한다고 들었습니다. https://sites.google.com/site/complingfiles/files/string.supp

+0

여기에 언급 된 링크는 더 이상 작동하지 않습니다. – Riot

+0

예, 학교에서 해당 수업을 java로 전환했습니다. 내가 어디에서든지 그것을 파낼 수 있는지 알게 될 것이다. –

+1

@Riot : 파일을 찾은 후 새 링크를 게시했습니다. –

2

내가 std::string과 오탐 (false positive)과 비슷한 문제를 가지고 프로그램의 끝 부분에 더 exit(0)이없는에도 불구하고 : 여기에 그들이 문자열을 우리에게 준 억제 파일입니다. 나는 정적으로 libstdc++와 연결했다. 연결 옵션을 공유로 전환하고 GLIBCXX_FORCE_NEW을 사용하여 컴파일하면 경고가 표시되지 않습니다.

+0

고마워요, 고마워요, 고마워요, 고마워요! –

+0

'GLIBCXX_FORCE_NEW' 플래그로 컴파일하는 것이 실제로 아무 것도하지 않는 것처럼 보입니다. [libstdC++ docs for mt_allocator] (https://gcc.gnu.org/onlinedocs/libstdc++/manual/mt_allocator_impl.html)에 따르면, 환경 변수입니다. "GLIBCXX_FORCE_NEW 환경 변수가 설정되면 bool _S_force_new를 true로 설정 한 다음 반환합니다." 그래서 간단히'export GLIBCXX_FORCE_NEW = 1;'과 같이하고 valgrind를 실행하십시오. 이것은 std :: string에서 많은 양의 문제를 해결해 오탐 (false positive)을 제공합니다. – BobTuckerman