簡體   English   中英

calloc實際分配多少內存?

[英]How much memory does calloc actually allocate?

經過測試的以下代碼將輸出顯示為

1
0
0
2
0

這是驚人的,因為ptr [3],ptr [4]沒有任何內存分配。 盡管他們在其中存儲了價值並打印出來。 我為ptr [i]中的幾個較大的i嘗試了相同的代碼,該代碼再次成功編譯並給出了結果,但是對於非常大的i值(約100000),程序崩潰了。 如果calloc()在單次調用中分配了如此大的內存,那么它就不值得有效。 那么calloc()如何工作? 這個差異在哪里?

#include <stdio.h>
void main() {
    int * ptr = (int *)calloc(3,sizeof(int));//allocates memory to 3 integer
    int i = 0;
    *ptr = 1;
    *(ptr+3) = 2;//although memory is not allocated but get initialized
    for( i =0 ; i<5 ; ++i){
        printf("%d\n",*ptr++);
    }
}

之后,我嘗試了此代碼,該代碼可以連續運行而沒有任何輸出

#include <stdio.h>
void main() {
int * ptr = (int *)calloc(3,sizeof(int));
int i = 0;
*ptr = 1;
*(ptr+3) = 2;
//free(ptr+2);
for( ; ptr!=NULL ;)
{
    //printf("%d\n",*ptr++);
    i++;
}
printf("%d",i);
}

您正在混淆兩種內存分配:內核的和libc的。

當您要求malloccalloc提供5個字節時,它不會掉頭並向內核請求5個字節。 那將永遠 相反,libc堆系統從內核獲取更大的內存塊,並將其細分。

因此,當您需要少量的內存時,通常在libc尚未分配的內存之后就有大量可訪問的內存,您可以訪問它。 當然,訪問它是漏洞的即時解決方案。

引用末尾的唯一時間將是SIGnal,這是如果您恰好位於從內核獲取的區域的最后。

我建議您嘗試在valgrind下運行測試用例,以獲取更多信息。

您擁有的代碼具有未定義的行為。 但是,您不會崩潰,因為malloccalloc實際上經常分配比您要求的更多的內存。

告訴您有多少內存的一種方法是調用增加大小的realloc ,直到您獲得的指針與原始指針不同為止。 盡管該標准不能保證該技巧會奏效,但通常會產生良好的效果。

您可以通過以下方法進行此實驗:

int *ptr = calloc(1,sizeof(int));
// Prevent expansion of the original block
int *block = calloc(1, sizeof(int));
int *tmp;
int k = 1;
do {
    tmp = realloc(ptr, k*sizeof(int));
    k++;
} while (tmp == ptr);
printf("%d\n", k-1);

這將在我的系統和ideone上打印4ideone上的演示 )。 這意味着當我請求4個字節(即calloc一個sizeof(int)時,我有足夠的空間可容納16個字節(即4 * sizeof(int) ). This does not mean that I can freely write up to four int s after requesting memory for a single但是, s after requesting memory for a single int` s after requesting memory for a single :超出請求的內存邊界寫入仍然是未定義的行為。

calloc在給定代碼段中為3 int分配內存。 實際上,您正在訪問未分配的內存。 訪問未分配的內存會調用未定義的行為

calloc僅分配您要求的內存量,在您的情況下為3個int變量

但是它不會在它創建的指針上創建一個邊界(在您的情況下是ptr)。 因此您只需增加指針即可訪問未分配的內存。 那就是您的情況。

暫無
暫無

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

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