2

C ++で互換的に使用deleteできるのはいつですか?free

私の懸念は次のとおりです。/と/の使用に誤った取り違えがあるとしましょう(/は言うまでmallocfreeあり newませんdelete)。しかし、同じことをします。 偶然にも、これはテストでは捕らえられません。後でこれは本番環境でのクラッシュにつながる可能性があります。new[]delete[]deletefree

これを防ぐために、どうすればある種のチェックを実施できますか?2つが混同された場合、警告できますか?コンパイル時でない場合は、実行時にコードインストルメンテーションを実行する可能性がありますか?これにどのようにアプローチしますか?

この質問の目的は、使用法の不注意による混同を回避する方法を見つけることです。

4

14 に答える 14

11

それらを混同しないようにする簡単な方法は、malloc()を使用しないことです。そうすれば、free()を呼び出したくなることはありません。この問題を回避するために作成するインフラストラクチャは「コードレビュー」と呼ばれますが、この場合、コードベースの「grepmalloc(」または「grepfree(」)で十分です。

于 2009-07-22T16:32:56.193 に答える
7

一度もない。それが機能する場合、それは実装のまったくの偶然によるものです。この動作に依存しないでください。

于 2009-07-22T16:30:32.267 に答える
5

2番目の質問に答えるために、malloc/freeoperator new/deleteの両方を制御する場合は、追加情報を隠して、それらがどのように割り当てられたかを示す、両方から返されるポインターに関連付けることができます。freeポインタがまたはに渡されたらoperator delete、適切な関数によってポインタが割り当てられていることを確認してください。そうでない場合は、例外をアサートまたは発生させるか、不一致を報告するために行うことを実行します。

通常、これは追加のメモリを割り当てることによって行われます。たとえば、与えられたmalloc(size)、または、そこに追加の情報operator new(size)を割り当てて押し込みます。size + additional space

于 2009-07-22T16:36:56.747 に答える
5

それらを混同しないようにする唯一の方法は、次のいずれかです。

  • そもそもmalloc/freeを使用しない、または
  • メモリの割り当てはRAIIに依存してください。RAIIオブジェクト内のすべてのメモリ割り当てを保護して、メモリがスコープ外になったときにメモリが正しく一貫して解放されるようにするか、割り当てをスマートポインタでラップします。

手動でdeleteまたはfreeを呼び出すことは、バグへの誘いにすぎません。

于 2009-07-22T16:41:03.103 に答える
4

オブジェクトのコンストラクタとデストラクタを呼び出すのは、常にC++で使用する必要がnewあります。deletenewdelete

両方を使用する必要がある場合(たとえば、Cライブラリとインターフェイスしている場合)、コードレビューを徹底的に行って、の使用free()に対応しているmalloc()かどうか、およびで使用されているかどうかを判断する必要があります。 Cコンテキスト。

于 2009-07-22T16:30:19.320 に答える
1

それを成文化する必要がある場合は、次のようなスタイルガイドを挿入します。

  • free()オブジェクトのプライベートポインタフィールドでのみ呼び出すことができます。
  • malloc()edバッファ(または呼び出し元が必要とするC APIから返されるバッファfree())は、オブジェクトのプライベートポインタフィールドに割り当てる必要があります。
  • 可能なバッファを保持するプライベートポインタフィールドfree()は、その目的でのみ使用する必要があります。
  • ハンガリアン記法を使用する場合は、そのための文字を追加します(使用しない場合は、追加しないでください)。
  • オブジェクトの存続期間中に-ableバッファが置き換えられた場合を除いて、通常free()はデストラクタでのみ呼び出されます。free()その場合free()、フィールド値を直接呼び出すのではなく、置換中にプライベートフィールドから最近コピーされた値を呼び出すことができます。

つまり、malloc/freeを使用するものすべてにラッパーを貼り付けます。このラッパーは、誰もが使用する単一のテンプレートにすることも、削除関数をに設定してスマートポインターを許可することもできますfree()。次に、コードレビューで、他の場所でmalloc / freeの呼び出しが表示された場合、それは間違っています。

基本的に、これが問題になるのを防ぐ最善の方法は、一般的なリソース処理の上に置くことです。free()Cでは、の代わりに誤ってストリームを呼び出すという大きな問題はありませんfclose()

于 2009-07-22T17:27:55.787 に答える
0

newで割り当てられたものを解放するときは、常にdeleteまたはdelete[]を使用する必要があります。同じことがmallocと無料にも当てはまります。

new:edクラスの削除にfreeを使用すると、デストラクタが適切に呼び出されません。また、newとdeleteは、割り当てに必ずしもmalloc / freeを使用するわけではないため、ヒープも破損する可能性があります。

于 2009-07-22T16:30:58.523 に答える
0

で割り当てられたもの、で割り当てられたもの、およびを使用deleteして割り当てられたものに常に使用します。newdelete []new []free()malloc()

newおよびnew[]は、malloc()とは異なるヒープから割り当て、間違ったfree()/ deleteを使用すると、間違ったヒープから割り当てを解除しようとします。

于 2009-07-22T16:36:06.657 に答える
0

とまたはと混合new/deletenew[]/delete[]ないでくださいmalloc()/free()。これに加えて、malloc()/free()C++での使用には少なくとも疑問があります。

これを誤って行わないようにする最も簡単な方法は、メモリを手動で管理しないことです。C ++には、文字列やその他のコンテナ、およびメモリ管理を処理するためのスマートポインタがあります。これを手動で行う必要はありません。(私が最後に入力したことを覚えているdeleteのが本当に最後に入力したのかどうかはわかりません。しかし私の記憶が失敗しなければ、これは2001年か2002年だったに違いありません。)

于 2009-07-22T16:42:48.653 に答える
0

new / new [] / mallocに追加のメモリを割り当てる独自のバージョンの関数を記述して、割り当てを行った関数を追跡できます。次に、delete / delete [] / freeをチェックインして、メモリを再利用するために適切な関数が使用されたことを確認します。この方法で、new []とdelete([]なし)の混合などを確認することもできます。デバッグビルドでは、これらのバージョンのみを使用することをお勧めします。

于 2009-07-22T16:51:40.510 に答える
0

アプリケーションでvalgrindを実行して、何かがキャッチされるかどうかを確認できます。このマニュアルでは、メモリブロックに対する誤った割り当て解除機能の使用をキャッチする機能について具体的に説明しています。ただし、コンパイル時にこれを行う方法はないと思います。

于 2009-07-22T16:52:34.080 に答える
0

malloc/freeまたはnew/deleteの誤用を回避する1つの方法は、これらの関数を直接呼び出さないで、ラッパー層によって呼び出すことです。ラッパーレイヤーでは、自分の手で配布されたポインターを管理し、誤用によって明示的にエラーが発生することを保証できます。

于 2013-04-10T09:13:21.577 に答える
-1

なぜあなたはmallocステートメントの総数を数え、それを無料の総数で数えないのですか?Newとdeleteについても同じようにします。プロセスは正規表現で自動化できます。

于 2009-07-22T16:57:40.420 に答える
-2

これに関連して私が行ったことの1つは、mallocを再実装してC ++で解放し、内部でnew/deleteを呼び出すようにすることです。最適ではありません が、小規模なプロジェクトでは十分に機能します。

于 2009-07-22T16:32:43.463 に答える