[英]Difference between using malloc and initializer for array?
為什么我必須free
使用malloc創建的數組,而不是使用初始化程序創建的數組?
float* rgba = malloc(4 * sizeof(float));
free(rgba);
與:
float rgba[] = { 0.0f, 0.0f, 0.0f, 0.0f };
free(rgba); // ERROR
在第二個引擎蓋下發生了什么?
在第一種情況下:
堆內存段中有分配。 無論在堆中分配的是什么,都必須由用戶取消分配。 編譯器不負責自動解除分配。
在第二種情況:
內存分配發生在堆棧或數據段中,具體取決於您是在函數內部還是全局分配數組!
如果在函數外部分配數組,它將在內存的數據段部分中分配。
如果在函數內部分配數組,它將在堆棧中分配。
無論在堆棧或數據段中分配的是什么,都會自動取消分配。 不需要從用戶側進行明確的解除分配。
區別在於malloc
始終從動態內存中分配內存,而初始化程序將數據放在靜態或自動內存中,具體取決於您定義rgba
的上下文:
static
,則rgba
將在靜態區域中分配,並獲得靜態或全局可見性 由於free
調用只能傳遞一個函數從malloc
系列返回的指針( malloc
/ calloc
/ realloc
)或其他返回動態內存的函數(例如strdup
),因此在非malloc-ed指針上調用free
是未定義的行為。
因為
float rgba[] = { 0.0f, 0.0f, 0.0f, 0.0f };
這里數組內存在堆棧上分配。 當程序超出范圍時,編譯器本身會釋放該內存。 如果你釋放它,編譯器將釋放它,它將是雙重免費的情況。
在第一個中,您將內存分配給堆。 用戶負責釋放用戶分配的堆內存。 這就是為什么第一種情況下的free
可行。
第一種情況是動態分配的內存,其中內存分配在內存的堆部分中。 這意味着在編譯之后,內存分配在運行時完成。
第二種情況是正常的局部變量創建,其中內存在編譯期間在內存的堆棧部分中分配。
free()函數用於取消分配僅在運行時分配的內存,而不是編譯時間 。 因此你會收到錯誤。
首先,您的任何示例中都沒有“指定的初始值設定項”。 您的第二個示例使用聚合初始化程序語法,而沒有任何實際的初始值設定項被“指定”。
其次,這與集合初始化器沒有任何關系。 主要區別在於左側:第一種情況下為float* rgba
,第二種情況下為float rgba[]
。
在第二種情況下,您實際上是聲明一個數組 ,它是一個本地或靜態數組(取決於該聲明所在的位置)。 本地和靜態內存不得free
釋放。 它根本無法取消分配。 您沒有本地或靜態內存,這意味着您的業務不用擔心其重新分配。 本地和靜態對象具有遵循預定規則的預定壽命。 它們完全按照這些規則自動創建和銷毀。
在第一種情況下,你根本沒有真正聲明一個數組。 您正在聲明指向動態分配的內存塊的指針 。 您擁有動態分配的所有內存塊,這意味着您有責任正確釋放它們。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.