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

时间:2013-01-12 06:51:52

标签: c++ memory memory-leaks

我使用valgrind --leak-check =全面检查我的程序,并且得到了一个我不知道的泄漏:

==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)”行。你能弄清楚泄漏是如何在那里完成的吗?

干杯

1 个答案:

答案 0 :(得分: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之后)。您的流很可能不包含十亿个字符,因此很大一部分缓冲区将保持未初始化状态。如果幸运的话,你会在某个地方找到一个NULL字符来终止你的流。

我不知道您是想要读取整个流还是只读一行。在后一种情况下,您可以将代码简化为:

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
}

希望这有帮助。