2016-12-06 173 views
0

讓我們假設我有這樣的代碼:分配給指針的指針:我是否應該釋放它?

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

注意p不使用其他任何地方和每個for週期獨立於其他。

讓我們假設z沒有那麼大,所以p不memmory方面貴。但是,n可能很大,因此p所佔用的總內存可能會一致。

是否正確free()它:

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

獎金的問題:如果時間的表現將是優先級(而不是內存的消耗),效果會更好,避免free(p),因爲它耗時?

+3

爲什麼C++標籤在這裏? –

+0

@EdgarRokyan你是對的。 – justHelloWorld

回答

4

既然你這個標記與C++,你不應該使用mallocfree。使用smart pointers(或new/delete,如果您無權訪問C++ 11兼容編譯器)。與

它是正確的釋放(),它...

是:

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 >''和我在外''使用'v' '循環?無論如何,'p'會在範圍的最後自動釋放? – justHelloWorld

+0

如果你使用'std :: vector >',你正在定義一個堆分配數組的可調整大小的數組。您可能需要'std :: vector '。我前段時間做了一個關於智能指針的視頻教程(https://www.youtube.com/watch?v=zMdD-s5_BIY) - 如果您喜歡通過視頻學習,我認爲這將是一個很好的開始。 –

3

您可以在週期前預先分配必要的內存量並重新使用它。

如果你不知道z有多大 - 我會建議在某處寫分配的內存大小,如果z比它大 - 然後重新分配,否則 - 只是重新使用已分配記憶。

+0

感謝您的回答。 'z'是高度可變的,可能只有幾百到幾十萬(這是SIFT算法檢測到的關鍵點的數量,完全取決於輸入圖像)。 – justHelloWorld

+0

然後只是重新分配,如果Z大於先前的高Z,內存已被分配。 – Starl1ght

0

是的。你必須free吧。否則,你有內存泄漏,這是不好的。特別是如果你循環很多次。

一個很好的經驗法則是每malloc必須匹配free。總是。 (這是對規模較大的項目尤其重要)

2

觀察:使用malloc。法:援引free。就這麼簡單。便攜式,定義明確的代碼需要mallocfree

分配的內存量在這裏沒有作用。如果內存太多,malloc會拋出一個錯誤,但這與您始終需要使用free來遵循malloc無關。

+0

感謝您的回答。但是,如果我們談論高性能應用程序,「免費」可能會耗費大量時間,所以即使內存效率低下,它的時間效率也會更高。 – justHelloWorld

+1

@justHelloWorld不要爲了效率而犧牲正確性。如果性能對您很重要,請預先分配內存並重新使用它,只需[如@ Starl1ght所述](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)正如你所說的那樣,要想出一個巧妙的方法來做到這一點。找到一個模式,想一些偷偷摸摸的方式,但不要忘記親愛的先生'免費'。 – 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

看起來大小是不變的,那麼爲什麼你要分配一次又一次呢? 在循環之前只分配一次,循環內初始化。 您可以重新使用內存。循環結束後釋放內存。

程序在循環結束後結束,那麼您不必釋放它,程序消耗的所有堆內存都將返回到操作系統,但釋放分配的內存總是一個好習慣。 關於獎勵問題,免費並不費時,但分配內存,所以不要擔心免費使用的時間。

0

如果您再次使用該內存 - 僅當您結束程序並僅分配一次程序(並且在需要更大/更小的陣列時使用realloc()重新分配),顯然更有效。

您可能編程的每個操作系統都會在程序終止時處理釋放動態分配的內存。但是,由於我們主要是儘量保持我們的代碼儘可能跨平臺,所以您應該始終使用動態分配的內存free()

至於如果你有一個巨大的存儲量和只顧速度 - 那麼顯然free() ING會「減慢」的方案,但它需要時間的量是如此之小得可笑,76*(10**-8)我卑微的機器上,對於一個1024字節的塊,所以它是相當不重要的。