3

私はvalgrindの初心者なので、何か間違ったことをするかもしれませんが、valgrindが割り当てよりも多くの無料を報告した場合はどうすればよいですか?

ここでSSCCEを取得しました:

#include <cstring>

class something
{
protected:
    char* ptr;
public:
    something() {ptr = NULL;}
    something(const char* value) {
        ptr = new char[strlen(value)+1]; strcpy(ptr, value);
    }
    ~something() {delete[] ptr; ptr = NULL;}
};

int main()
{
    something x;
    x = "123";
    return 0;
}

これは正常にコンパイルされ、正常に実行されますが、valgrindは言います

==15925== Invalid free() / delete / delete[]
==15925==    at 0x40221EA: operator delete[](void*) (vg_replace_malloc.c:364)
==15925==    by 0x8048689: something::~something() (test.cpp:12)
==15925==    by 0x80485F5: main (test.cpp:19)
==15925==  Address 0x42b7028 is 0 bytes inside a block of size 4 free'd
==15925==    at 0x40221EA: operator delete[](void*) (vg_replace_malloc.c:364)
==15925==    by 0x8048689: something::~something() (test.cpp:12)
==15925==    by 0x80485E5: main (test.cpp:18)
==15925==
==15925== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 18 from 1)
==15925== malloc/free: in use at exit: 0 bytes in 0 blocks.
==15925== malloc/free: 1 allocs, 2 frees, 4 bytes allocated.
==15925== For counts of detected errors, rerun with: -v
==15925== All heap blocks were freed -- no leaks are possible.

理由はわかりません。
もちろん、私は知識に基づいた推測をすることができます-明らかに問題のある行はそれが言うところx = "123";です、そしてあなたがそれをコメントするならば、すべては良いです。しかし、なぜそれでは、コンパイラーは、たとえそれでも、これで問題ないと考えるの-Wall -Wextra -pedanticでしょうか。このプログラムに問題があることを教えてくれるコンパイラスイッチを忘れましたか?

4

3 に答える 3

1

x = "123"x = something("123")は、暗黙のコピー代入演算子を呼び出すと同等です。一時的なsomethingものは破棄されますが、同じ生のポインターxである も破棄されます。delete []

解決策は、 Rule of Threeに従うか、スマート ポインター/コンテナーを使用してメモリ管理を行うことです。

于 2012-04-28T12:50:32.503 に答える
1

Rule of threeを実装するのを忘れていました。
コピー コンストラクターとコピー代入演算子を提供する必要があります。

x = "123";

object の浅いコピーを作成する暗黙的に生成されたコピー代入演算子を呼び出し、一時が破棄されると、デストラクタは割り当てられたメモリの割り当てを解除し、ポインター メンバーをダングリング ポインターとして残します。

于 2012-04-28T12:50:45.313 に答える
0

クラスsomethingには、(コンパイラが提供する) コピー コンストラクターと代入演算子によって適切に管理されていない生のポインターが含まれています。生のポインタを使用しないでください。必要な場合は、クラス メソッドをより慎重に定義してください。しかし、実際には、生のポインターを使用しないでください。

于 2012-04-28T12:50:37.293 に答える