2014-03-06 106 views
1

我得到一個內存泄漏getline,我不知道爲什麼或如何阻止它。getline()valgrind內存泄漏

下面是從Valgrind的報告:

==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一些更行:

string line; 

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

我認爲它有話當getline失敗,並且因爲行是string,它不知何故不會釋放該內存。我如何防止這種情況?

readOption也使用getline但我認爲它沒有內存泄漏,因爲string line在本地定義,然後超出範圍,有效地清理內存?

編輯1:

我已讓虛擬函數「解決」問題:

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

但它似乎愚蠢的做到這一點,我不知道爲什麼Valgrind是抱怨,如果有沒有泄漏。我仍然對這個問題採取更好的/乾淨的解決方案。

+0

您顯示的所有變量都具有自動存儲持續時間。他們不能泄漏。 –

+0

我不知道如何理解valgrind的抱怨,然後 – ParoX

+0

我今天已經看到這個(幾乎)相同的問題... –

回答

3

當你通過調用函數exit()退出一個C++程序,對象的析構函數將不會運行。這可能會導致Valgrind報告內存泄漏。

0

或許C++中類的問題正在用指針的東西,暗示可能泄漏行爲Valgrind的。

我獲取有關此診斷中,其中我分配一些陣列的一個項目,但後來我調整指針到第三元件,使得指數爲[-2]和[-1]被用來存儲一些元信息。沒有泄漏,因爲我恢復指針並正確釋放陣列。

Valgrind的看到該對象被引用但是,他們沒有提及「很好」通過指針到他們的基地地址,但只能通過內部指針。它看起來像是一個可能的泄漏,因爲沒有用於釋放對象的指針。

像這樣的情況可能發生在漏方案:方案是,比方說,分配一個大對象,其他模塊給(通過指針),它的一部分,然後泄漏大對象。內部指針確實表明泄漏。

這可能是getlinebasic::string<>的表示巧合,並做了這樣的事情。當您複製對象時,新對象不會做任何有趣的事情:它只是通過其基址引用字符串數據。舊對象消失了,它釋放了數據。

只是一個假設。

順便說,在上述程序,我通過保留一個額外的指針在矢量對象管理這些數組的基地址固定東西Valgrind的。這個額外的指針只有當軟件是爲Valgrind調試而構建時(以及其他功能,如使用Valgrind客戶端請求API)纔會出現。

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)強制程序退出而不調用析構函數的任何,因爲據我所知 - 從來就只去過使用C++一個半月,所以我不是一個真正的專家。