簡體   English   中英

使用malloc和realloc進行動態存儲的最佳方法

[英]optimal way of using malloc and realloc for dynamic storing

我試圖弄清楚使用malloc和realloc從用戶那里收集未知數量的字符,存儲它們以及僅在結束時打印它們的最佳方法。

我認為調用realloc太多次都不會那么聰明。 所以相反,我每次都分配一定量的空間,讓我們說sizeof char * 100並在文件的末尾,我使用realloc來精確地擬合整個事物的大小。

你覺得怎么樣?這是一個好方法嗎? 你會走另一條路嗎?

請注意,我無意使用鏈表,getchar(),putchar()。 僅使用malloc和realloc是必須的。

如果重新分配以適應所需的確切數據量,那么您將優化內存消耗。 這可能會導致代碼變慢,因為1)您獲得額外的realloc調用; 2)您可能無法分配適合CPU對齊和數據緩存的數量。 可能這也會導致堆分段問題,因為重復的reallocs,在這種情況下它實際上可能浪費內存。

通常很難回答什么是“最佳”,但下面的方法相當常見,因為它是降低realloc調用的執​​行速度和降低內存使用之間的良好折衷:

您分配一個段,然后跟蹤該段的用戶數據量。 分配size_t mempool_size = n * _Alignof(int);是個好主意size_t mempool_size = n * _Alignof(int); 使用可被8整除的n也可能是明智的。

每次在此段中耗盡可用內存時,都會重新分配到mempool_size*2個字節。 這樣你每次都可以將可用內存增加一倍。

我認為調用realloc太多次都不會那么聰明。

你是怎么想出來的? 因為真正了解的唯一方法是衡量績效。

您的策略可能需要根據您從用戶讀取數據的方式而有所不同。 如果您使用的是getchar()那么每次讀取一個字符時,您可能不希望使用realloc()將緩沖區大小增加一個char。 但是,即使在這些情況下,一個好的realloc()也會比你想象的低效率低得多。 我認為,glibc實際上為了響應malloc()而給出的最小塊大小是16個字節。 因此,從0到16個字符並且每次重新分配不涉及任何復制。 類似地,對於較大的重新分配,可能不需要分配新塊,可以使現有塊更大。 不要忘記,即使是最慢的, realloc()也會比人們輸入的更快。

大多數人不會采取這種策略。 輸入的內容可以通過管道傳輸,因此人們不能快速打字的論點不一定有效。 通常,您會介紹容量的概念。 您分配具有特定容量的緩沖區,當它滿了時,您可以通過添加特定大小的新塊來增加其容量(使用realloc() )。 初始大小和重新分配大小可以通過各種方式進行調整。 如果您正在讀取用戶輸入,則可能需要較小的值,例如256個字節,如果您正在從磁盤或網絡上讀取文件,則可能需要更大的值,例如4Kb或更大。

增量大小甚至不需要是常量,您可以選擇將每個所需重新分配的大小加倍。 這是一些編程庫使用的策略。 例如,我相信哈希表的Java實現使用它,因此可能是數組的Cocoa實現。

事先不可能知道在任何特定情況下最佳策略是什么。 我會選擇一些感覺正確的東西然后,如果應用程序有性能問題,我會做測試來調整它。 您的代碼不一定是最快的,但速度足夠快。

然而,我絕對不會做的一件事是在內置分配器的頂部覆蓋一個家庭滾動內存算法。 如果你發現自己維護了一個你沒有使用的塊列表而不是釋放它們,那么你做錯了。 這就是讓OpenSSL陷入困境的原因。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM