2012-10-27 43 views
4

我有一個關於我的應用程序設計的問題。 下面是僞代碼:我如何知道要重新分配多少內存?

char* buffer_to_be_filled = (char*) malloc(somesize); 
fill_the_buffer(buffer_to_be_filled); 
free(buffer_to_be_filled); 

的問題是,我不知道fill_the_buffer多大尺寸要求。

我在想fill_the_buffer函數裏面的解決方案。 我也許可以在需要時重新分配裏面的空間;問題是,有沒有辦法找出我有多少空間?

這通常如何解決?我認爲分配緩衝區的人也應該重新分配緩衝區,對吧?

注:我使用fread函數填充緩衝區,所以我不知道我需要多少空間。

回答

3

您的函數不能realloc傳遞給它的指針,因爲realloc不能保證返回它傳遞的相同指針(新緩衝區可能太大而無法在原地展開)。典型的解決方案是讓函數獲取指定緩衝區大小的第二個參數,並在緩衝區太小時返回錯誤代碼。理想情況下,錯誤代碼會告訴用戶緩衝區需要多大,以便他們可以自行重新分配並調用該函數。例如,從手冊頁snprintf(其具有此問題):

的功能的snprintf()和vsnprintf()不寫比大小字節(包括終止空字節以上(「\ 0」) )。如果輸出由於此限制而被截斷,則返回值是在足夠空間可用的情況下將被寫入最終字符串的字符數(不包括終止空字節)。因此,大小或更大的返回值意味着輸出被截斷。

3

您必須將緩衝區大小傳遞給fill_the_buffer函數。如果緩衝區不夠大,你的函數必須返回一個錯誤值(f/e -1)。如果成功,您的函數可以返回寫入字節的數量。這種方法是C語言的慣例。

2

似乎fill_the_buffer()功能處於更有利的位置就知道...
- 如何開始和/或
維緩衝區 - 何時重新ALLOC緩衝區,並通過有多大。

因此,可以適當地改變API:

char * fill_the_buffer()
或也許
char * fill_the_buffer(size_t max_amount_caller_wants)

呼叫者fill_the_buffer()將仍然是負責由該函數返回的緩衝器的設置,但分配和維度將留給函數的邏輯。

此方法通常遵循將實現細節留在較低級別的想法,使得上層更具可讀性。

+0

ok,所以如果一個函數分配一些東西,它仍然是一個很好的「設計」,我檢索它,我負責釋放,我知道它會工作,我只是想確保這是一個普遍的做法 –

+0

@javo你可以這樣做,但這實際上並不常見。通常分配內存的函數是釋放內存的函數。要麼將緩衝區傳遞給要填充的函數,要麼將函數保留在內部的靜態緩衝區中,下次調用它時會被覆蓋 –

+2

是的。我理解你對試圖用同樣的方法保持分配和釋放的擔憂。然而這種方法並不少見;當使用這種模式時,建議以更明確的方式命名該函數,以便分配一個新的緩衝區,例如'Get_Data_From_XYZ()'或類似的東西,還可以評論API的明確性,關於需要調用者在不再需要時釋放緩衝區。 – mjv

0

我有一個建議,如果你在分配的可用內存沒有問題:
在使用malloc節目的開頭分配的初始大小,(儘量做出很好的猜測,這個最初分配),然後在fill_the_buffer中,您可能需要分配更多的內存,或者您可能不需要全部分配的內存。在第一種情況下,您可以在某些步驟中分配適量的內存(取決於您的可用內存的應用程序&)(例如每次泄漏10MB)&然後恢復填充緩衝區直到需要更多內存&緩衝區填充時重複此操作。 在第二種情況下,您可以簡單地使用realloc來減少緩衝區分配內存的大小。
但是要特別注意使用realloc當你想增加緩衝區的大小時,因爲它通常會造成很大的開銷(它必須找到一個足夠大的空閒內存部分,然後將所有舊數據拷貝到新部分&免費舊部分)。

相關問題