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

「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。「abcd」などの 4 文字の場合、length変数にはビット パターン41424344(16 進数) が含まれます。10 進数では、これは1094861636です。基本的に、ストリームから次の 10 億文字を読み取ろうとします (abcd前に抽出した後)。ストリームに 10 億文字が含まれていない可能性が非常に高いため、バッファのかなりの部分が初期化されないままになります。運が良ければ、ストリームを終了する 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 に答える