简体   繁体   English

返回字符串时可能发生内存泄漏?

[英]possible memory leak when returning a string?

I use valgrind --leak-check=full check my program, and got a leak which I have no idea with: 我使用valgrind --leak-check = full检查我的程序,并发现了一个我不知道的泄漏:

==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)

Here's my code snippet: 这是我的代码段:

#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("");
}

It's pointing to the "return string(buf)" line. 它指向“返回字符串(buf)”行。 Can you figure out how the leak is done there? 您能弄清楚那里的泄漏如何发生吗?

Cheers 干杯

Okay, I am not really sure what you are trying to do here. 好的,我不确定您要在这里做什么。 For your writeString method (why should it be a method if it does not use any members?), you should pass the stream as reference, and your string as constant reference. 对于您的writeString方法(如果不使用任何成员,为什么应该是一个方法?),则应将流作为引用传递,并将字符串作为常量引用传递。 Your code could be simplified to this: 您的代码可以简化为:

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

No need to fiddle with pointers and buffers yourself if the standard already does that for you. 如果标准已经为您做到了,则无需摆弄指针并进行缓冲。

As for your readString "method": It seems you try to read 4 characters ( sizeof(length) ) and store them in length . 至于您的readString “ method”:看来您尝试读取4个字符( sizeof(length) )并将它们存储为length If you have 4 characters, say "abcd", your length variable contains the bit pattern 41424344 (hexadecimal). 如果您有4个字符,例如说“ abcd”,则length变量包含位模式41424344 (十六进制)。 In decimal, this is 1094861636 . 十进制为1094861636 Basically, you then try to read the next billion characters from your stream (after the abcd you extracted earlier). 基本上,您然后尝试读取流中的下一个十亿个字符(在您先前提取的abcd之后)。 It is quite likely that your stream does not contain one billion characters, so a good portion of your buffer will be left uninitialized. 您的流很可能不包含十亿个字符,因此缓冲区的很大一部分将保持未初始化状态。 If you are lucky, you find a NULL character somewhere which terminates your stream. 如果幸运的话,您会在某个地方找到一个NULL字符来终止您的流。

I do not know if you want to read the entire stream or just a line. 我不知道您是要阅读整个流还是仅阅读一行。 In the latter case, you could simplify your code to: 在后一种情况下,您可以将代码简化为:

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
}

Hope this helps. 希望这可以帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM