メインコンテンツ

void ポインターが削除されています

オブジェクトを指す void* ポインターに対し delete を実行

説明

この欠陥は、delete 演算子が void* ポインターに作用した場合に発生します。

リスク

C++ 規格によると、void* ポインターの削除は未定義です。

オブジェクトがタイプ MyClass であり、delete 演算子がそのオブジェクトを指す void* ポインターで実行される場合、MyClass デストラクターは呼び出されません。

デストラクターに、リソースの解放やカウンターの値を減らすなどのクリーンアップ操作が含まれている場合、その操作は実行されません。

修正方法

void* ポインターを適切な型にキャストします。delete 操作をキャストの結果に対して実行します。

たとえば、void* ポインターが MyClass オブジェクトを指す場合は、ポインターを MyClass* にキャストします。

すべて展開する

#include <iostream>

class MyClass {
public:
    explicit MyClass(int i):m_i(i) {}
    ~MyClass() {
        std::cout << "Delete MyClass(" << m_i << ")" << std::endl;
    }
private:
    int m_i;
};

void my_delete(void* ptr) {
    delete ptr;
}


int main() {
    MyClass* pt = new MyClass(0);
    my_delete(pt);
    return 0;
}

この例では、関数 my_deletedelete 操作を任意の型に対して実行するよう設計されています。ただし、関数本体では、delete 操作が void* ポインター ptr に作用します。したがって、my_delete をタイプ MyClass の引数を指定して呼び出す場合、MyClass デストラクターは呼び出されません。

修正 — void* ポインターを MyClass* にキャスト

1 つの解決策として、my_delete について、関数の代わりに関数テンプレートを使用します。

#include <iostream>

class MyClass {
public:
    explicit MyClass(int i):m_i(i) {}
    ~MyClass() {
        std::cout << "Delete MyClass(" << m_i << ")" << std::endl;
    }
private:
    int m_i;
};


template<typename T> void safe_delete(T*& ptr) {
    delete ptr;
    ptr = NULL;
}


int main() {
    MyClass* pt = new MyClass(0);
    safe_delete(pt);
    return 0;
}

結果情報

グループ: 適切な手法
言語: C++
既定値: オフ
コマンド ライン構文: DELETE_OF_VOID_PTR
影響度: Low

バージョン履歴

R2015b で導入