2016-12-06 12 views
0

のは、私はこのコードを持っているとしましょう:他の場所で使用され、各forサイクルは他から独立していないポインタの割り当て先:解放する必要がありますか?

for (int i=0;i<n;i++) { 
    //compute z 
    float *p = (float *) malloc (sizeof(float)*z); 
    //do something with p 
} 

お知らせpこと。

はのは、zはそれほど大きくないので、単一pがmemmoryの面でその高価ではないと仮定しよう。ただし、nは潜在的に大きいので、合計メモリはpとなります。

for (int i=0;i<n;i++) { 
    //compute z 
    float *p = (float *) malloc (sizeof(float)*z); 
    //do something with p 
    free(p); 
} 

ボーナス質問:

は、それはそれはしてfree()に正しいです時間のパフォーマンスを優先(とないメモリ消費量)であるかどうそれは時間がかかるなので、free(p)を避けるために良いだろう?

+3

なぜC++タグがここにありますか? –

+0

@EdgarRokyanあなたが正しいです。 – justHelloWorld

答えて

4

(これは、大規模なプロジェクトでは特に重要です)。 smart pointers(またはC++ 11コンパイラにアクセスできない場合はnew/deleteを使用してください。

は(自由にそれが正しいです)、それを...

はいて:あなたの質問に答えるために

for (int i=0;i<n;i++) { 
    // compute z 
    std::unique_ptr<float[]> p{new float[z]}; 
    // do something with p 
    // p gets automatically freed at the end of the scope 
} 

mallocで何かを割り当てる場合は、常にfreeにする必要があります。

時間がかかりますので無料(p)を避ける方が良いでしょうか?

はい。ループの外側でメモリの場所を事前に割り当てることを検討してください。

// preallocate 
std::unique_ptr<float[]> p{new float[z]}; 

for (int i=0;i<n;i++) { 
    // clear p 
    // compute z 
    // do something with p 
} 

// p gets automatically freed at the end of the scope 
+0

あなたの答えをありがとう。私はスマートポインタを使ったことはありませんでしたが、私の質問は、 '' v.push_back(p) '' 'std :: vector >'を実行し、 '' 'ループ?とにかく 'p'は自動的にスコープの終わりに解放されますか? – justHelloWorld

+0

'std :: vector >'を使用する場合は、ヒープ割り当て配列のサイズ変更可能なサイズ変更可能な配列を定義しています。おそらく 'std :: vector 'が代わりに必要です。スマートポインタに関するビデオチュートリアル(https://www.youtube.com/watch?v=zMdD-s5_BIY)を少し前に作成しました。あなたがビデオを通して学ぶことを楽しむなら、始めるのが良い場所だと思います。 –

3

サイクルの前に必要なメモリ量を事前に割り当てて再利用することができます。

もし、あなたがどれくらいの大きさを知らないのであれば - 割り当てられたメモリのサイズをどこかに書くことをお勧めします。zがそれより大きい場合 - 再割り当てしてください。メモリ。

+0

あなたの答えをありがとう。 'z'は非常に可変であり、何百もの数百(SIFTアルゴリズムによって検出されるキーポイントの数であり、これは入力画像に完全に依存する)です。 – justHelloWorld

+0

その後、Zがメモリが既に割り当てられていた以前の高Zより大きい場合は、再割り当てします。 – Starl1ght

0

はい。それはfreeでなければなりません。それ以外の場合は、メモリリークがありますが、これは悪いです。特に多くの回数ループする場合。

すべてのmallocは、freeと一致する必要があります。常に。あなたはC++でこれをタグ付けされているので、あなたがmallocfreeを使用しないでください

2

観察:mallocが使用されます。 Act:freeを呼び出します。それはそれと同じくらい簡単です。ポータブルで明確なコードは、mallocfreeが必要です。

割り当てられたメモリ量はここでは何の役割も果たしません。メモリが多すぎる場合は、mallocはエラーをスローしますが、それはに続くには常にfreeが必要であるという事実とは関係ありません。

+0

あなたの答えをありがとう。しかし、高性能アプリケーションについて話していると、「フリー」に時間がかかることがあります。したがって、メモリが非効率的であっても、時間の点でより効率的になる可能性があります。 – justHelloWorld

+1

@justHelloWorld正確性を犠牲にして効率化を図ってはいけません。パフォーマンスが重要な場合は、メモリをあらかじめ割り当てて再利用するだけです([@ Starl1ght said](http://stackoverflow.com/a/40992293/3494013)。どの場合でも、 'malloc'の後に' free'を呼び出します。そして、メモリの量が「非常に可変」である場合(http://stackoverflow.com/questions/40992251/pointer-allocated-in-for-should-i-have-to-free-it/40992321#comment69193323_40992293)あなたが言ったように、そうでなければそれを行うための巧妙な方法を思いついてください。パターンを見つけ、いくつかの卑劣な方法を考えるが、親愛なるMr.フリーを忘れないでください。 – Downvoter

+1

ロジャー、私は彼を忘れないだろう:D – justHelloWorld

0

不必要な割り当てを避けるために再利用されるバッファの使用を検討してください。これはstd::vector<float>を使用することによって非常に簡単に行うことができます。

std::vector<float> p; 
for (int i=0;i<n;i++) { 
    //compute z 
    p.resize(z); 
    //do something with p 
} 

あなたはO(log n)メモリの割り当てを取得し、最悪の場合。あなたのコードでは、nのメモリ割り当てが得られます。 free()を呼び出さないとメモリリークが発生します。 std::vector<float>が自動的にメモリを自動的にクリーンアップします。

0

サイズは一定であるようですが、なぜそれを何度も何度も割り当てたいのですか? ループの前に1回だけ割り当てます。ループの内側は最初に初期化されます。 メモリを再利用できます。そして、ループが終了したらメモリを解放します。

ループの後にプログラムが終了してから解放する必要はありません。プログラムが消費したヒープメモリはすべてOSに返されますが、割り当てたメモリを解放することをお勧めします。 ボーナスに関する質問では、無料は時間がかかりませんが、メモリを割り当てることは無料ですので、時間がかかることは心配しないでください。

0

メモリをもう一度再利用する場合は、プログラムを終了して一度だけ割り当てたときに解放するほうが効率的です(大小の配列が必要な場合はrealloc()を使用して再割り当てしてください)。

プログラムが終了したときに動的に割り当てられたメモリを解放するために、おそらくプログラムするすべてのOSが処理されます。しかし、私たちがコードをできるだけクロスプラットフォームに保つことを主眼にしているので、常にfree()のメモリを動的に割り当ててください。

あなたは膨大な量のメモリがあり、スピードだけを気にかけているなら、明らかにfree() ingはプログラムの速度を落としますが、時間がかかりすぎるので、私の謙虚なマシンでは76*(10**-8)、 1024バイトのチャンクのため、それはかなり重要ではありません。

関連する問題