簡體   English   中英

使用 calloc() 為 0 個元素分配內存?

[英]memory allocation for 0 elements with calloc()?

實際上,我希望這里有一個警告/錯誤,但它編譯沒有任何問題。 為什么可以使用 0 個對象作為第一個參數調用 calloc 函數? 為什么它為此分配內存?

int* p_integer=calloc(0, sizeof(int));

if(!p_integer){
    exit(EXIT_FAILURE); 
}

//prints 4 
printf("size *p_integer: %zu\n", sizeof(*p_integer));

好的,補充幾點:

void* calloc( size_t num, size_t size );


Allocates memory for an array of num objects of size and initializes all bytes in the 
allocated storage to zero.

If allocation succeeds, returns a pointer to the lowest (first) byte in the allocated 
memory block that is suitably aligned for any object type.

If size is zero, the behavior is implementation defined (null pointer may be returned, 
or some non-null pointer may be returned that may not be used to access storage) 

https://en.cppreference.com/w/c/memory/calloc

這怎么理解? 在我的情況下,大小(第二個參數)不為零,對嗎? 因此,如果第一個參數 == 零,則沒有對這種情況的解釋。 或者我是否必須計算 0*sizeof(int) == 0(請求的內存塊的大小)。 他們是什么“尺寸”?

為什么可以使用 0 個對象作為第一個參數調用 calloc 函數? (OP)

這是可能的,因為庫的 C 規范說它是允許的。 然而,內存分配為 0 是一種邊緣情況,會導致實現定義的行為

C17/18 最近在該領域更新為:

如果請求的空間大小為零,則行為是實現定義的:要么返回空指針以指示錯誤,要么行為就好像大小是某個非零值一樣,但不應使用返回的指針訪問一個對象。 C17dr § 7.22.3 1


為什么它為此分配內存? (OP)

沒有證據表明分配了任何內存,只是為 OP 返回了一個非NULL指針。 它不能用於引用任何內存。

我是否必須計算 0*sizeof(int) == 0(請求的內存塊的大小)。 他們是什么“尺寸”?

“大小”是產品(沒有size_t范圍限制)。 對象的大小從不為 0 包括sizeof(int) ,因此只有n需要測試。 使用calloc(n, sz) ,其中兩者都是變量,我將使用if (n == 0 || sz == 0)進行測試,而不是執行會帶來溢出問題的乘法。


為了避免這種實現定義的行為,首先測試參數。 例子:

int *p = (n > 0) ? calloc(n, sizeof *p) : malloc(1);
if (p == NULL) Oops();
...
free(p);

或者,為了說明實現定義的行為,可能不是calloc(0, sizeof *p)返回NULL出錯。

int *p = calloc(n, sizeof *p);
if (p == NULL && n > 0) Oops();
...
free(p);

[這個答案解決了我們希望callocmalloc在請求時提供零字節內存的原因。 它沒有解決 C 標准對它的描述。]

考慮編寫一個程序來檢查一些輸入並可能對各種事物進行分類,制作類別 C1、C2 等中的數據列表。 稍后,軟件將處理 C1 的所有數據,然后處理 C2 的所有數據,依此類推。

考慮哪個更簡單和更短:

  • 該程序為N 個列表項分配空間並處理N 個列表項,無論N是零還是正數,此代碼都有效。
  • 程序必須明確測試N並根據N是零還是正數使用不同的代碼路徑。

前一種選擇更簡單、更短、更干凈。 通常,它為錯誤提供的機會較少。 當軟件必須根據N是零還是正數而有不同的路徑時,程序員可能會忽略零的情況,從而導致錯誤。

零大小的 malloc,calloc 是 100% OK。 free就OK

p_integer*p_integer sizeof沒有使用取消引用指針 - 它是 100% OK

您可以為p_integer分配任何值 - 但如果 malloc 或 calloc 返回有效的非空指針,它將導致潛在的內存泄漏;

暫無
暫無

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

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