2013-01-12 70 views
0

我使用的valgrind --leak檢查=全檢查我的計劃,並得到了泄漏,我不知道有:返回字符串時可能的內存泄漏?

==6072== 54 bytes in 2 blocks are possibly lost in loss record 15 of 28 
==6072== at 0x4C2AF8E: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) 
==6072== by 0x55B63B8: std::string::_Rep::_S_create(unsigned long, unsigned long, std::allocator<char> const&) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.17) 
==6072== by 0x55B7D94: char* std::string::_S_construct<char const*>(char const*, char const*, std::allocator<char> const&, std::forward_iterator_tag) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.17) 
==6072== by 0x55B7E72: std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.17) 
==6072== by 0x4268ED: Writable::readString(std::istream*) (Writable.cpp:33) 

這裏是我的代碼片段:

#include "Writable.h" 

Writable::Writable() 
{ 
    //ctor 
} 

Writable::~Writable() 
{ 
    //dtor 
} 


void Writable::writeString(ostream* ofs, string str){ 
    int length = str.size()+1; 

    ofs->write((char*)&length, sizeof(length)); 

    if (length > 1) 
     ofs->write(str.c_str(), length); 

} 

string Writable::readString(istream* ifs) { 
    int length = 0; 

    ifs->read((char*)&length, sizeof(length)); 

    if(length > 1) { 
     char buf[length]; 
     ifs->read(buf, length); 

     return string(buf); 
    } 

    return string(""); 
} 

它指向「返回字符串(buf)」行。你能弄清楚如何在那裏完成泄漏?

乾杯

+0

可變長度數組不是標準C++的一部分。無論如何,返回一個'std :: string'沒有問題,當你這樣做的時候你不需要強制轉換。 – chris

+0

返回「普通」字符串時會得到什麼? 'string Foo(){string bar =「Hello,World」;返回欄; }' –

+1

'int length = 0; char buf [length];'你怎麼能編譯? – billz

回答

0

好吧,我不太確定你在這裏做什麼。對於你的writeString方法(爲什麼它應該是一個不使用任何成員的方法?),你應該將該流作爲參考,並將你的字符串作爲常量引用。您的代碼可以簡化爲這樣:

void Writable::writeString(std::ostream & ofs, std::string const & str){ 
    ofs << str; 
} 

無需使用指針和緩衝區自己搗鼓如果標準已經不適合您。

至於你的readString「方法」:看起來你試圖讀取4個字符(sizeof(length))並將它們存儲在length。如果您有4個字符,請說「abcd」,您的length變量包含位模式41424344(十六進制)。十進制,這是1094861636。基本上,您然後嘗試從您的流中讀取下一個十億個字符(在之前提取的abcd之後)。您的流很可能不包含十億個字符,因此很大一部分緩衝區將保持未初始化狀態。如果你幸運的話,你會在某處找到一個空字符來終止你的流。

我不知道你是想讀整個流還是隻讀一行。在後一種情況下,可以簡化您的代碼:

std::string Writable::readString(std::ostream & ofs){ 
    std::string extracted; 
    getline(ofs, extracted); 
    return std::move(extracted); // or return extracted; if you have a pre C++11 compiler 
} 

希望這有助於。