誤ったメモリー割り当て解除

不適切な値がメモリーの割り当て解除ルーチンに渡されています。

このエラーは、メモリーの割り当て解除ルーチンに渡される値が、対応するメモリー割り当てルーチンの呼び出しからのものではないことを示します。このエラーは、次の 2 つの場合に発生します。1 つ目は、静的変数のアドレスや文字列リテラルなど、割り当てられていないものを解放しようとした場合です。2 つ目は、あるメモリー・アロケーターの割り当てルーチンから取得された値を、別のメモリー・アロケーターの割り当て解除ルーチンに渡そうとした場合です。例えば、"malloc" から取得された値は "delete" ではなく、"free" によって割り当て解除を行う必要があります。

C++ には、"delete" と "delete []" (配列デアロケーター) の 2 つの delete の形式があります。この 2 つの違いは、自明でない (non-trivial) デストラクターを持つクラス・オブジェクトの配列を解放する場合にのみ見られます。この場合、配列デアロケーターは配列内の各オブジェクトに対してデストラクターを呼び出しますが、通常のデアロケーターは呼び出しません。このような場合に配列デアロケーターの代わりに通常のデアロケーターを呼び出すと、C++ オブジェクト・セマンティクスに違反し、メモリーリークやその他のエラーを引き起こす可能性があります。

一般に、配列アロケーターから取得されたオブジェクトは、通常のデアロケーターを使用する方が安全な場合でも、常に配列デアロケーターで割り当てを解除する必要があります。これにより、デコンストラクターが自明でなくなる (non-trivial) ような方法でクラスが変更された場合でも、エラーを防ぐことができます。この診断は、通常のデアロケーターが単純なオブジェクトの配列の解放に使用された場合には出力されません。

1 つのポインター変数を使用して、異なるタイミングで異なるアロケーターから取得された値を保持すると、ストレージの割り当てを適切に解除する方法がわかりづらいため、避けた方が良いでしょう。

ID

問題箇所

説明

1

解放サイト

不適切な値が解放された場所


#include <stdlib>

// A class with non-trivial destructor
class NonTrivial {
private:
    char *m_string;
public:
    // Constructor allocates m_string
    NonTrivial() { m_string = new char[10]; }
    
    // Destructor frees m_string
    ~NonTrivial() { delete m_string; }
    
    // Copy constructor doesn't copy m_string field
    NonTrivial(const NonTrivial & source)
      : m_string(new char[10])
    {
        for (int i = 0; i < 10; i++) {
            m_string[i] = source.m_string[i];
        }
    }

    // Assignment operator doesn't assign m_string field
    NonTrivial& NonTrivial::operator=(const NonTrivial & source)
    {
        for (int i = 0; i < 10; i++) {
            m_string[i] = source.m_string[i];
        }
        return *this;
    }
};

char c;
NonTrivial glob;

int main(int argc, char **argv)
{
    NonTrivial *p1 = new NonTrivial[10];
    NonTrivial *p2 = new NonTrivial(glob); // copy constructor
    char *p3 = "abcd";
    char *p4 = &c;
    *p1 = *p2;
    *p4 = *p3; // assignment operator
    delete p1; // bad: should use delete []
    free(p2);  // bad: should use delete
    free(p3);  // bad: not allocated object
    free(p4);  // bad: not allocated object
    delete &glob; // bad: not allocated object
}
        

© 2010 Intel Corporation. 無断での引用、転載を禁じます。