0

我使用 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)

这是我的代码片段:

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

干杯

4

1 回答 1

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
}

希望这可以帮助。

于 2013-01-12T12:05:22.767 回答