簡體   English   中英

使用malloc和數組初始值設定項之間的區別?

[英]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.

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