2009-08-13 10 views
3

私はC++のdelete []演算子について疑問に思います。 (私はVisual Studio 2005を使用しています)。delete []とメモリリーク

管理対象DLLによって呼び出されているアンマネージDLLがあります。デバッグ中にいくつかのタスクを実行した後にこのプログラムを終了すると、サイズが44バイト(24バイト〜44バイト)のメモリリークが数多く発生しています。私は、次のコードがあれば私が理解から、とにかく

、:そして、すべてのメモリを

char* pointer = new char[500] 
/* some operations... */ 
delete[] pointer; 

を、それが正しく解放されるために、私は右ですか?

char* pointer = new char[500]; 
char* pointerIt = pointer; 
/* some code perhaps to iterate over the whole memory block, like so */ 
for (int i = 0; i < 250; i++){ // only iterate halfway 
    *pointerIt = 0; 
    pointerIt++; 
} 

delete[] pointer; 

メモリを指さポインタだけ右に削除されます。私は、次のコードを持っているときに何が起こるか

?ポインタが有効なメモリを指していないことを意味します。しかし、両方のポインタをNULLに設定することができます

char* pointerFirstPosition = new char[500]; 
char* pointerIt = pointerFirstPosition; 

for (int i = 0; i < 250; i++){ // only iterate halfway 
    *pointerIt = 0; 
    pointerIt++; 
} 

delete[] pointerIt; // delete the pointer iterator... 

このコードはpointerIt 500までpointerItによって指さにメモリブロックを削除します:私はこれを行う場合

とにかく、何が今、どうなりますか?またはpointerFirstPosが指すメモリブロックをpointerFirstPos + 500に削除しますか?

メモリリークが発生する可能性がありますか?

申し訳ありませんが、長いメッセージのために、メッセージをはっきりと伝えようとしています。

おかげで、

クレブス

+1

「しかし、私は右、NULLに両方のポインタを設定することができるので、それは大丈夫です?」さて、あなたはポインタを使って行うべきです... – GManNickG

答えて

4

最初の質問のセット:それは正しく を解放されるために

char* pointer = new char[500] 
/* some operations... */ 
delete[] pointer; 

その後、すべてのメモリは、私は右ですか?

右。

2番目の質問のセット:

char* pointer = new char[500]; 
char* pointerIt = pointer; 
/* some code perhaps to iterate over the whole memory block, like so */ 
for (int i = 0; i < 250; i++){ // only iterate halfway 
    *pointerIt = 0; 
    pointerIt++; 
} 

delete[] pointer; 

メモリがポインタによっては は右削除されますか?つまり、 pointerItは有効な メモリを指していないことを意味します。しかし、それはOKです。 両方のポインタをNULLに設定することはできますか?

メモリpointerは完全に削除されています。 pointerpointerItの両方が無効なメモリのアドレスを保持しています。各ポインタは単なる変数であり、すべての変数は独立しています。したがって、両方とも互いに独立した独自のアドレスを格納します。逆参照演算子*は、単にそのアドレスに変数を渡します。そのアドレスの変数は、ポインタ変数とは異なる変数です。

3番目の質問のセット:

あなたは、割り当てられたアドレスのみ、配列全体を削除する必要があります。部分配列を削除しようとすると、結果が未定義になります。メモリリークが発生する可能性はありますか?おそらく、クラッシュする可能性がありますか?おそらく、それは....になる可能性がありますか?おそらく。

あなたが割り当てたものだけを削除してください。配列を割り当てる場合、deleteで削除する配列ではない型を削除すると、delete[]で削除されます。

char* pointer = new char[500]; 
char* pointerIt = pointer; 
//This is fine because you are deleting the same address: 
delete[] pointerIt; 
//The memory that both variables point to is freed, do not try to free again 
+2

'new'や' new [] 'を使って作成したもの以外のものは、' delete'や 'delete []'に定義されていません。 – GManNickG

+0

ありがとう、それは私が疑ったものでした。しかし、たとえば、3番目の質問セットでは、私はpointerIt = pointerFirstPositionを設定し、次に[] pointerItを削除します。これはまだ未定義ですか?私は他の誰かの古いコードと一緒に働いていて、彼はすでに会社を辞めてしまいました。これがメモリリークの理由であるかどうかを判断しようとしています。 – krebstar

+0

ちょうどキックのために、g ++ 4.4.1の下でこれをテストしました - 基本的に3番目のコードサンプルにあるものと同じコードですが、 'pointerIt'を除いて配列の途中で動いています。 'pointerIt'で' delete [] 'を呼び出すと' pointer'が無効になりますが、動作が未定義の場合、この動作はすべてのコンパイラから期待できません。 –

0

チェックアウトブースト:: shared_ptrのか::後押しscoped_ptrをして、もう一度このことを心配しない:ここで

だけで明確にするためで結構です何かのeampleです。 これは、あなたのメモリを管理する静的&参照カウント方法を提供します。

http://www.boost.org/doc/libs/1_39_0/libs/smart_ptr/shared_ptr.htm

+1

これを行うと私は非常に多くのプロジェクトを変更する必要があります。:(私のマネージャーが正当化できない何か – krebstar

+0

将来のコードのために 'std :: vector'とkinを使用します。 * ever **。 – GManNickG

+0

ありがとう、ありがとう、とても役に立ちます:) – krebstar