2014-03-06 2 views
1

누출. 나는 그것이 뭔가를 가지고 있다고 생각의 getline() Valgrind의 메모리는 내가의 getline와 메모리 누수를 얻고, 내가 왜하거나 중지하는 방법을 잘 모르겠습니다

string line; 

bool pending = getline(inputfile, line); 
int round = readOption(inputfile); 
int num = readOption(inputfile); 

:

여기
==26681== 
==26681== HEAP SUMMARY: 
==26681==  in use at exit: 1,756 bytes in 73 blocks 
==26681== total heap usage: 223 allocs, 150 frees, 15,523 bytes allocated 
==26681== 
==26681== 28 bytes in 1 blocks are possibly lost in loss record 1 of 4 
==26681== at 0x4A075BC: operator new(unsigned long) (vg_replace_malloc.c:298) 
==26681== by 0x4CCC4B8: std::string::_Rep::_S_create(unsigned long, unsigned long, std::allocator<char> const&) (new_allocator.h:94) 
==26681== by 0x4CCD227: std::string::_Rep::_M_clone(std::allocator<char> const&, unsigned long) (basic_string.tcc:631) 
==26681== by 0x4CCD30F: std::string::reserve(unsigned long) (basic_string.tcc:512) 
==26681== by 0x4CCD5D4: std::string::append(char const*, unsigned long) (basic_string.tcc:310) 
==26681== by 0x4C86384: std::basic_istream<char, std::char_traits<char> >& std::getline<char, std::char_traits<char>, std::allocator<char> >(std::basic_istream<char, std::char_traits<char> >&, std::basic_string<char, std::char_traits<char>, std::allocator<char> >&, char) (istream.cc:397) 
==26681== by 0x4026ED: main (test.cpp:210) 
==26681== 
==26681== LEAK SUMMARY: 
==26681== definitely lost: 0 bytes in 0 blocks 
==26681== indirectly lost: 0 bytes in 0 blocks 
==26681==  possibly lost: 28 bytes in 1 blocks 
==26681== still reachable: 1,728 bytes in 72 blocks 
==26681==   suppressed: 0 bytes in 0 blocks 
==26681== Reachable blocks (those to which a pointer was found) are not shown. 
==26681== To see them, rerun with: --leak-check=full --show-reachable=yes 
==26681== 
==26681== For counts of detected and suppressed errors, rerun with: -v 
==26681== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 6 from 6) 

는 Test.cpp에

bool pending = getline(inputfile, line); 

라인 (210) 좀 더 줄 수 있습니다 : 여기

는 Valgrind의에서 보고서입니다 getline이 실패 할 때, 그리고 라인이 string이기 때문에 어떻게 든 메모리를 할당 해제하지 않습니다. 어떻게 이것을 막을 수 있습니까?

readOption도 getline을 사용합니다. 그러나 string line이 로컬에 정의되어 있고 메모리를 효과적으로 정리하기 때문에 메모리 누수가 없다고 생각합니까?

편집 1 :이 경우 Valgrind의 불평 왜 나는 확실하지 않다,

bool getnewline(ifstream &inputfile) { 
    string line; 
    return getline(inputfile, line); 
} 

는 이렇게 바보 같다 그러나 :

나는 더미 기능을하여 문제를 "해결"했다 누설 없음. 나는 여전히이 문제에 대해 더 나은/깨끗한 해결책을 찾은 것이다.

+0

표시된 모든 변수에는 자동 저장 기간이 있습니다. 누출 될 수 없습니다. –

+0

valgrind의 불평을 이해하는 방법을 모르겠습니다. – ParoX

+0

오늘 (거의) 같은 질문을 이미 보았습니다 ... –

답변

3

exit() 함수를 호출하여 C++ 프로그램을 종료하면 개체 소멸자가 실행되지 않습니다. Valgrind가 메모리 누수를보고 할 수 있습니다.

0

아마 C++ 클래스는 Valgrind에게 누출되는 동작을 암시하는 포인터로 뭔가를하고있을 것입니다.

일부 배열을 할당하는 프로젝트에서이 문제에 대한 진단을 받지만 인덱스 [-2]와 [-1]이 일부 메타 정보를 저장하는 데 사용되도록 포인터를 세 번째 요소로 조정합니다. 포인터를 복원하고 배열을 올바르게 비우기 때문에 누수가 없습니다.

그러나 Valgrind는 객체가 참조되는 것을 확인하지만 기본 주소에 대한 포인터를 통해 "내부 포인터"를 통해 "멋지게"참조되지는 않습니다. 개체를 해제하기위한 포인터가 없으므로 가능한 누출 인 것처럼 보입니다.

이와 같은 상황은 새는 프로그램에서 발생할 수 있습니다. 즉, 큰 개체를 할당하고, 포인터를 통해 포인터를 통해 다른 개체에 할당 한 다음 큰 개체를 유출하는 프로그램입니다. 내부 포인터는 누수를 제안합니다.

getlinebasic::string<>의 표현으로 불쾌하고 그 종류의 것을 할 수 있습니다. 객체를 복사 할 때 새 객체는 아무 것도하지 않습니다. 단지 문자열 데이터를 기본 주소로 참조합니다. 오래된 개체는 사라지고 데이터가 해제됩니다.

그냥 가설

.

그런데이 프로그램에서 Valgrind는 그 배열을 관리하는 벡터 객체에서 기본 주소에 대한 여분의 포인터를 유지함으로써 고정되었습니다. 이 여분의 포인터는 Valgrind 클라이언트 요청 API 사용과 같은 다른 기능과 함께 Valgrind 디버깅을 위해 소프트웨어가 빌드 된 경우에만 나타납니다.

1

나는 이것이 거의 1 년 전이지만 getline() 메모리 누수 문제를 특별히 찾아서이 특정 문제를 재현 할 수있는 방법에 대한 최소한의 지침을 제공하고자한다. std :: string 변수를 정의하고 프로그램에서 완전히 종료하지 않아야합니다.

을 감안할 때 다음

leaky.cpp :

#include <iostream> 
int main(int argc, char ** argv) { 
    std::string x = "x"; 
    exit(1); 
    return 0; 
} 

컴파일 문자열 :

g++ -g -Wall -Wpedantic --std=gnu++11 leaky.cpp -o leaky 

Valgrind의 호출 :

valgrind --tool=memcheck --leak-check=full ./leaky 

이 있음을 발표 할 예정이다 이렇게 ...에서 증서 누출 :

==4434== Memcheck, a memory error detector 
==4434== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al. 
==4434== Using Valgrind-3.10.0.SVN and LibVEX; rerun with -h for copyright info 
==4434== Command: ./leaky 
==4434== 
==4434== 
==4434== HEAP SUMMARY: 
==4434==  in use at exit: 16 bytes in 1 blocks 
==4434== total heap usage: 1 allocs, 0 frees, 16 bytes allocated 
==4434== 
==4434== 16 bytes in 1 blocks are possibly lost in loss record 1 of 1 
==4434== at 0x402A6DC: operator new(unsigned int) (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so) 
==4434== by 0x40F8213: std::string::_Rep::_S_create(unsigned int, unsigned int, std::allocator<char> const&) (in /usr/lib/i386-linux-gnu/libstdc++.so.6.0.19) 
==4434== by 0x40FA125: char* std::string::_S_construct<char const*>(char const*, char const*, std::allocator<char> const&, std::forward_iterator_tag) (in /usr/lib/i386-linux-gnu/libstdc++.so.6.0.19) 
==4434== by 0x40FA7AF: std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&) (in /usr/lib/i386-linux-gnu/libstdc++.so.6.0.19) 
==4434== by 0x804875E: main (leaky.cpp:3) 
==4434== 
==4434== LEAK SUMMARY: 
==4434== definitely lost: 0 bytes in 0 blocks 
==4434== indirectly lost: 0 bytes in 0 blocks 
==4434==  possibly lost: 16 bytes in 1 blocks 
==4434== still reachable: 0 bytes in 0 blocks 
==4434==   suppressed: 0 bytes in 0 blocks 
==4434== 
==4434== For counts of detected and suppressed errors, rerun with: -v 
==4434== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0) 

물론이 질문에 대한 답변을 포함하려고 종료 (1) 내가 아는 한, 어떤 소멸자를 호출하지 않고 종료 프로그램을 강제로 - I've 만하고 한 달 반 동안 C++을 사용하기 때문에 전문가가 아닙니다.