發(fā)布于:2021-02-09 09:55:20
0
234
0
在學習C動態(tài)內存分配之前,讓我們先了解一下:
C中的內存管理是如何工作的?
當使用基本數據類型聲明變量時,C編譯器會自動為名為堆棧的內存池中的變量分配內存空間。
例如,一個float變量在聲明時通常需要4個字節(jié)(根據平臺)。我們可以使用sizeof操作符驗證此信息,如下面的示例所示。
#include <stdio.h>
int main() { float x; printf("The size of float is %d bytes", sizeof(x)); return 0;}
輸出為:
The size of float is 4 bytes
另外,在連續(xù)的內存塊中分配一個指定大小的數組,每個塊的大小為一個元素:
#include <stdio.h>
int main() { float arr[10];
printf("The size of the float array with 10 element is %d", sizeof(arr)); return 0;}
結果是:
The size of the float array with 10 element is 40
到目前為止,在聲明基本數據類型或數組時,內存是自動管理的。但是,在C中有一個分配內存的過程,它允許您實現(xiàn)一個數組大小尚未確定的程序,直到您運行程序(運行時)。此過程稱為“動態(tài)內存分配”。
C中的動態(tài)內存分配
動態(tài)內存分配是根據您的編程需要手動分配和釋放內存。動態(tài)內存由指針管理和服務,指針指向我們稱之為堆的區(qū)域中新分配的內存空間。
現(xiàn)在您可以在運行時動態(tài)地創(chuàng)建和銷毀元素數組,而不會出現(xiàn)任何問題。綜上所述,自動內存管理使用堆棧,C動態(tài)內存分配使用堆。
<stdlib.h>庫具有負責動態(tài)內存管理的功能。
函數 | 目的 |
malloc() | 分配請求大小的內存,并將指針返回到分配空間的第一個字節(jié)。 |
calloc() | 為數組的元素分配空間。將元素初始化為零并返回指向內存的指針。 |
realloc() | 它用于修改先前分配的內存空間的大小。 |
Free() | 釋放或清空先前分配的內存空間。 |
我們來討論一下上述函數及其應用。
C malloc()函數
C malloc()函數表示內存分配。它是一個用于動態(tài)分配內存塊的函數。它保留指定大小的內存空間,并返回指向內存位置的空指針。返回的指針通常是void類型。這意味著我們可以將C malloc()函數賦給任何指針。
malloc()函數的語法:
ptr = (cast_type *) malloc (byte_size);
ptr是cast類型的指針。
C malloc()函數返回一個指向字節(jié)大小的分配內存的指針。
malloc()的示例:
ptr = (int *) malloc (50)
當此語句成功執(zhí)行時,將保留50字節(jié)的內存空間。保留空間的第一個字節(jié)的地址分配給int類型的指針ptr
再舉一個例子:
#include <stdlib.h>
int main(){
int *ptr;
ptr = malloc(15 * sizeof(*ptr)); /* a block of 15 integers */
if (ptr != NULL) {
*(ptr + 5) = 480; /* assign 480 to sixth integer */
printf("Value of the 6th integer is %d",*(ptr + 5));
}
}
輸出:
Value of the 6th integer is 480
注意,sizeof(*ptr)被用來代替sizeof(int),以便在以后將*ptr聲明類型轉換為不同的數據類型時使代碼更加健壯。
如果內存不足,分配可能會失敗。在本例中,它返回一個空指針。因此,應該包含檢查空指針的代碼。
請記住,分配的內存是連續(xù)的,可以將其視為數組。我們可以使用指針算法來訪問數組元素,而不是使用括號[]。我們建議使用+來引用數組元素,因為使用incrementation++或+=會更改指針存儲的地址。
Malloc()函數還可以與字符數據類型以及復雜數據類型(如結構)一起使用。
free()函數
在編譯時自動釋放變量的內存。在動態(tài)內存分配中,必須顯式釋放內存。如果不這樣做,您可能會遇到內存不足錯誤。
調用free()函數來釋放/釋放C中的內存。通過釋放程序中的內存,您可以在以后使用更多的可用內存。
例如:
#include <stdio.h>
int main() {
int* ptr = malloc(10 * sizeof(*ptr));
if (ptr != NULL){
*(ptr + 2) = 50;
printf("Value of the 2nd integer is %d",*(ptr + 2));
}
free(ptr);
}
輸出
Value of the 2nd integer is 50
C calloc()函數
C calloc()函數表示連續(xù)分配。此函數用于分配多個內存塊。它是一種動態(tài)內存分配函數,用于將內存分配給數組和結構等復雜的數據結構。
Malloc()函數用于分配單個內存空間塊,而C中的calloc()函數用于分配多個內存空間塊。calloc()函數分配的每個塊大小相同
calloc()函數的語法:
ptr = (cast_type *) calloc (n, size);
上述語句用于分配相同大小的n個內存塊。
分配內存空間后,所有字節(jié)都初始化為零。
返回當前位于分配內存空間第一個字節(jié)的指針。
每當分配內存空間時出現(xiàn)錯誤(如內存不足),就會返回空指針。
calloc()的示例:
#include <stdio.h>
int main() {
int i, * ptr, sum = 0;
ptr = calloc(10, sizeof(int));
if (ptr == NULL) {
printf("Error! memory not allocated.");
exit(0);
}
printf("Building and calculating the sequence sum of the first 10 terms n ");
for (i = 0; i < 10; ++i) { * (ptr + i) = i;
sum += * (ptr + i);
}
printf("Sum = %d", sum);
free(ptr);
return 0;
}
下面的程序計算算術序列的和。
結果:
Building and calculating the sequence sum of the first 10 terms
Sum = 45
calloc()與malloc():關鍵區(qū)別
以下是C中malloc()和calloc()的主要區(qū)別:
calloc()函數通常比malloc()函數更合適、更有效。雖然這兩個函數都用于分配內存空間,但calloc()可以一次分配多個塊。你不必每次都請求內存塊。calloc()函數用于需要較大內存空間的復雜數據結構中。
由C中的calloc()分配的內存塊總是初始化為零,而在C中的函數malloc()中,它總是包含一個垃圾值。
C realloc()函數
使用Crealloc()函數,可以向已分配的內存添加更多內存大小。它在保持原始內容不變的同時擴展當前塊。C中的realloc()表示內存的重新分配。
realloc()還可用于減小先前分配的內存的大小。
realloc()函數的語法:
ptr = realloc (ptr,newsize);
上面的語句在變量newsize中分配一個指定大小的新內存空間。執(zhí)行函數后,指針將返回到內存塊的第一個字節(jié)。新的大小可以大于或小于以前的內存。我們不能確定新分配的塊是否指向與前一個內存塊相同的位置。此函數將復制新區(qū)域中以前的所有數據。它確保了數據的安全。
realloc()的示例:
#include <stdio.h>
int main () {
char *ptr;
ptr = (char *) malloc(10);
strcpy(ptr, "Programming");
printf(" %s, Address = %un", ptr, ptr);
ptr = (char *) realloc(ptr, 20); //ptr is reallocated with new size
strcat(ptr, " In 'C'");
printf(" %s, Address = %un", ptr, ptr);
free(ptr);
return 0;
}
每當C中的realloc()導致一個不成功的操作時,它都會返回一個空指針,并且之前的數據也會被釋放。
C語言中的動態(tài)數組
C語言中的動態(tài)數組允許元素的數量根據需要增長。C動態(tài)數組在計算機科學算法中有著廣泛的應用。
在下面的程序中,我們在C中創(chuàng)建了一個動態(tài)數組并調整了其大小。
#include <stdio.h>
int main() {
int * arr_dynamic = NULL;
int elements = 2, i;
arr_dynamic = calloc(elements, sizeof(int)); //Array with 2 integer blocks
for (i = 0; i < elements; i++) arr_dynamic[i] = i;
for (i = 0; i < elements; i++) printf("arr_dynamic[%d]=%dn", i, arr_dynamic[i]);
elements = 4;
arr_dynamic = realloc(arr_dynamic, elements * sizeof(int)); //reallocate 4 elements
printf("After reallocn");
for (i = 2; i < elements; i++) arr_dynamic[i] = i;
for (i = 0; i < elements; i++) printf("arr_dynamic[%d]=%dn", i, arr_dynamic[i]);
free(arr_dynamic);
}
C動態(tài)數組程序在屏幕上的結果:
arr_dynamic[0]=0
arr_dynamic[1]=1
After realloc
arr_dynamic[0]=0
arr_dynamic[1]=1
arr_dynamic[2]=2
arr_dynamic[3]=3
摘要
我們可以通過根據需要在堆中創(chuàng)建內存塊來動態(tài)管理內存。
在C動態(tài)內存分配中,內存是在運行時分配的。
動態(tài)內存分配允許操作大小靈活且可以在程序中隨時更改的字符串和數組。
當您不知道某個特定結構要占用多少內存時,就需要這樣做。
C語言中的Malloc()是動態(tài)內存分配函數,代表內存分配,該內存分配將具有特定大小的內存塊初始化為垃圾值。
C中的Calloc()是一個連續(xù)的內存分配函數,該函數一次將多個內存塊初始化為0。
C語言中的Realloc()用于根據指定的大小重新分配內存。
Free()函數用于清除動態(tài)分配的內存。