2011-12-07 9 views
-3

この非常に簡単なコードは、複雑な環境で発生するワイルドポインタの問題を示しています。ワイルドポインタを検出または防止する方法

int main() 
{ 
    int *a1 = new int; 
    int *tmp = a1; 
    delete a1; 
    // Now, the tmp pointer is a wild pointer, it's dangerous. 

    int *a2 = new int; 
    delete tmp; 
    // Now, the a2 pointer may be a wild pointer. 
} 

問題を検出または防止する方法はありますか?スマートポインタはここで助けますか?

+7

¤はいそれはです正解なぜ聞いたの? –

+3

2回目の 'delete'は未定義の動作を引き起こします。 – interjay

+0

@Alf P. Steinbach実際には、いくつかのプロジェクトが野生の問題を検出するのを助けるので、スマートポインタを除いて他の方法を尋ねたいと思うので、コードの変更は少なくて済みます。 –

答えて

2

スマートポインタを使用します。何故なの?

あなたが持っているコードは無効で、未定義の動作につながりますが、C++はメモリ使用量に関してはそれほど厳しくはありません。それはその美しさ(そして呪い)です。漏れを検出するのに役立つ外部ツールがありますが(実際にはそうではありませんが)基本的に正しい構造を使用して正しくプログラミングすることになります。 C++は多くの柔軟性を可能にしますが、正しく使用されなければ、あなたは厄介なバグを受け取ります。

2

valgrindのようなツール(少なくともLinuxでは)を使用して、このようなバグを追跡することができます。

また、Boehm's garbage collectorを使用することもできます(メモリの解放については気にしません)。

いくつかの(IMHO設計が間違っている)クラスは、削除する必要があります(つまり、デストラクタで重要なことを行い、メモリを解放するため)。

RAIIについてもっと詳しく読む(C++では非常に一般的ですが、一般的なマントラではありません:良いOcamlコードはそれに従わないなど)。

スマートポインタを使用できます。

+3

"彼らはデストラクタで重要なことをするから"そう、それはRAIIの一部です。 – tstenner

+0

ahahahahahaha ... C++の標準ライブラリのほとんどのように、ひどく設計されたクラスです。 – Mankarse

+0

@Mankarse:彼らはトップノッチではないかもしれませんが、彼らはまだあなたが野生で見つけるものよりもリーグです。 – GManNickG

0

唯一の方法は、できるだけコードを単体テストし、valgrindのようなツールを使用してプログラムと単体テストを実行し、すべてのメモリアクセスの問題をキャッチすることです。

0
int *a2 = new int; 
delete tmp; 
//now, the a2 pointer may be a wild pointer 

いいえ、ポインタa2は有効な(自由ではない)位置を指します。

私が知る限り、ポインタがメモリ自体に有効な(フリーではない)場所を指しているかどうかを調べる方法はありません。

最初の例では、std::shared_ptrを使用して、この共有所有権を割り当てられたメモリ上にモデル化することができます。

0

Cでは、誰も足に自分自身を射撃することを妨げません。

、このようなスマートポインタC++のように、自分の人生楽にする方法、あります、後続のアクセスが検出されたと報告できるようなvalgrindのようhttp://en.wikipedia.org/wiki/Smart_pointer#C.2B.2B_Smart_Pointers

ツールは、delete文をオーバーライドし、無効としてメモリをマークしますが、 。たとえば、デバッグ時に突き出される0xDEADBEEFなどの値を使用して、削除されると想定されるメモリを上書きすると、削除されたメモリ領域にアクセスしていることをすぐに知ることができます。

通常は、書き込みをスキップして不要なメモリにスキップして、デバッグモードでのみ有効にする必要があります。

2

この問題を解決するには、非常に簡単です:

は常に、コード内のリソースの所有権を明確にすること、およびリソースの寿命を管理するクラスを使用して、この所有権を施行します。この場合

、(あなたはすべてのポインタを使用する必要があると仮定して)次のように、私は示唆している寿命は次のとおりです:「スマートポインタと...」

//Limit the scope of the variables to the minimum required: 
{ 
    //a1 owns the pointer, so make it a `unique_ptr` 
    std::unique_ptr<int> a1(new int); 
    //tmp does not own the pointer, so make it a raw pointer 
    //limit its scope to a shorter scope than a1 
    int *tmp = a1.get(); 
} 
//now the tmp pointer does not exist. It cannot be dangerous 

//A similar strategy applies here 
{ 
    //a2 owns the pointer 
    std::unique_ptr<int> a2(new int); 
} 
//Again, a2 goes out of scope before any damage can occur. 
関連する問題