發(fā)布于:2021-02-09 09:55:20
0
223
0
在學(xué)習(xí)C動(dòng)態(tài)內(nèi)存分配之前,讓我們先了解一下:
C中的內(nèi)存管理是如何工作的?
當(dāng)使用基本數(shù)據(jù)類(lèi)型聲明變量時(shí),C編譯器會(huì)自動(dòng)為名為堆棧的內(nèi)存池中的變量分配內(nèi)存空間。
例如,一個(gè)float變量在聲明時(shí)通常需要4個(gè)字節(jié)(根據(jù)平臺(tái))。我們可以使用sizeof操作符驗(yàn)證此信息,如下面的示例所示。
#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ù)的內(nèi)存塊中分配一個(gè)指定大小的數(shù)組,每個(gè)塊的大小為一個(gè)元素:
#include <stdio.h>
int main() { float arr[10];
printf("The size of the float array with 10 element is %d", sizeof(arr)); return 0;}
結(jié)果是:
The size of the float array with 10 element is 40
到目前為止,在聲明基本數(shù)據(jù)類(lèi)型或數(shù)組時(shí),內(nèi)存是自動(dòng)管理的。但是,在C中有一個(gè)分配內(nèi)存的過(guò)程,它允許您實(shí)現(xiàn)一個(gè)數(shù)組大小尚未確定的程序,直到您運(yùn)行程序(運(yùn)行時(shí))。此過(guò)程稱(chēng)為“動(dòng)態(tài)內(nèi)存分配”。
C中的動(dòng)態(tài)內(nèi)存分配
動(dòng)態(tài)內(nèi)存分配是根據(jù)您的編程需要手動(dòng)分配和釋放內(nèi)存。動(dòng)態(tài)內(nèi)存由指針管理和服務(wù),指針指向我們稱(chēng)之為堆的區(qū)域中新分配的內(nèi)存空間。
現(xiàn)在您可以在運(yùn)行時(shí)動(dòng)態(tài)地創(chuàng)建和銷(xiāo)毀元素?cái)?shù)組,而不會(huì)出現(xiàn)任何問(wèn)題。綜上所述,自動(dòng)內(nèi)存管理使用堆棧,C動(dòng)態(tài)內(nèi)存分配使用堆。
<stdlib.h>庫(kù)具有負(fù)責(zé)動(dòng)態(tài)內(nèi)存管理的功能。
函數(shù) | 目的 |
malloc() | 分配請(qǐng)求大小的內(nèi)存,并將指針?lè)祷氐椒峙淇臻g的第一個(gè)字節(jié)。 |
calloc() | 為數(shù)組的元素分配空間。將元素初始化為零并返回指向內(nèi)存的指針。 |
realloc() | 它用于修改先前分配的內(nèi)存空間的大小。 |
Free() | 釋放或清空先前分配的內(nèi)存空間。 |
我們來(lái)討論一下上述函數(shù)及其應(yīng)用。
C malloc()函數(shù)
C malloc()函數(shù)表示內(nèi)存分配。它是一個(gè)用于動(dòng)態(tài)分配內(nèi)存塊的函數(shù)。它保留指定大小的內(nèi)存空間,并返回指向內(nèi)存位置的空指針。返回的指針通常是void類(lèi)型。這意味著我們可以將C malloc()函數(shù)賦給任何指針。
malloc()函數(shù)的語(yǔ)法:
ptr = (cast_type *) malloc (byte_size);
ptr是cast類(lèi)型的指針。
C malloc()函數(shù)返回一個(gè)指向字節(jié)大小的分配內(nèi)存的指針。
malloc()的示例:
ptr = (int *) malloc (50)
當(dāng)此語(yǔ)句成功執(zhí)行時(shí),將保留50字節(jié)的內(nèi)存空間。保留空間的第一個(gè)字節(jié)的地址分配給int類(lèi)型的指針ptr
再舉一個(gè)例子:
#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)被用來(lái)代替sizeof(int),以便在以后將*ptr聲明類(lèi)型轉(zhuǎn)換為不同的數(shù)據(jù)類(lèi)型時(shí)使代碼更加健壯。
如果內(nèi)存不足,分配可能會(huì)失敗。在本例中,它返回一個(gè)空指針。因此,應(yīng)該包含檢查空指針的代碼。
請(qǐng)記住,分配的內(nèi)存是連續(xù)的,可以將其視為數(shù)組。我們可以使用指針?biāo)惴▉?lái)訪(fǎng)問(wèn)數(shù)組元素,而不是使用括號(hào)[]。我們建議使用+來(lái)引用數(shù)組元素,因?yàn)槭褂胕ncrementation++或+=會(huì)更改指針存儲(chǔ)的地址。
Malloc()函數(shù)還可以與字符數(shù)據(jù)類(lèi)型以及復(fù)雜數(shù)據(jù)類(lèi)型(如結(jié)構(gòu))一起使用。
free()函數(shù)
在編譯時(shí)自動(dòng)釋放變量的內(nèi)存。在動(dòng)態(tài)內(nèi)存分配中,必須顯式釋放內(nèi)存。如果不這樣做,您可能會(huì)遇到內(nèi)存不足錯(cuò)誤。
調(diào)用free()函數(shù)來(lái)釋放/釋放C中的內(nèi)存。通過(guò)釋放程序中的內(nèi)存,您可以在以后使用更多的可用內(nèi)存。
例如:
#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()函數(shù)
C calloc()函數(shù)表示連續(xù)分配。此函數(shù)用于分配多個(gè)內(nèi)存塊。它是一種動(dòng)態(tài)內(nèi)存分配函數(shù),用于將內(nèi)存分配給數(shù)組和結(jié)構(gòu)等復(fù)雜的數(shù)據(jù)結(jié)構(gòu)。
Malloc()函數(shù)用于分配單個(gè)內(nèi)存空間塊,而C中的calloc()函數(shù)用于分配多個(gè)內(nèi)存空間塊。calloc()函數(shù)分配的每個(gè)塊大小相同
calloc()函數(shù)的語(yǔ)法:
ptr = (cast_type *) calloc (n, size);
上述語(yǔ)句用于分配相同大小的n個(gè)內(nèi)存塊。
分配內(nèi)存空間后,所有字節(jié)都初始化為零。
返回當(dāng)前位于分配內(nèi)存空間第一個(gè)字節(jié)的指針。
每當(dāng)分配內(nèi)存空間時(shí)出現(xiàn)錯(cuò)誤(如內(nèi)存不足),就會(huì)返回空指針。
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;
}
下面的程序計(jì)算算術(shù)序列的和。
結(jié)果:
Building and calculating the sequence sum of the first 10 terms
Sum = 45
calloc()與malloc():關(guān)鍵區(qū)別
以下是C中malloc()和calloc()的主要區(qū)別:
calloc()函數(shù)通常比malloc()函數(shù)更合適、更有效。雖然這兩個(gè)函數(shù)都用于分配內(nèi)存空間,但calloc()可以一次分配多個(gè)塊。你不必每次都請(qǐng)求內(nèi)存塊。calloc()函數(shù)用于需要較大內(nèi)存空間的復(fù)雜數(shù)據(jù)結(jié)構(gòu)中。
由C中的calloc()分配的內(nèi)存塊總是初始化為零,而在C中的函數(shù)malloc()中,它總是包含一個(gè)垃圾值。
C realloc()函數(shù)
使用Crealloc()函數(shù),可以向已分配的內(nèi)存添加更多內(nèi)存大小。它在保持原始內(nèi)容不變的同時(shí)擴(kuò)展當(dāng)前塊。C中的realloc()表示內(nèi)存的重新分配。
realloc()還可用于減小先前分配的內(nèi)存的大小。
realloc()函數(shù)的語(yǔ)法:
ptr = realloc (ptr,newsize);
上面的語(yǔ)句在變量newsize中分配一個(gè)指定大小的新內(nèi)存空間。執(zhí)行函數(shù)后,指針將返回到內(nèi)存塊的第一個(gè)字節(jié)。新的大小可以大于或小于以前的內(nèi)存。我們不能確定新分配的塊是否指向與前一個(gè)內(nèi)存塊相同的位置。此函數(shù)將復(fù)制新區(qū)域中以前的所有數(shù)據(jù)。它確保了數(shù)據(jù)的安全。
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;
}
每當(dāng)C中的realloc()導(dǎo)致一個(gè)不成功的操作時(shí),它都會(huì)返回一個(gè)空指針,并且之前的數(shù)據(jù)也會(huì)被釋放。
C語(yǔ)言中的動(dòng)態(tài)數(shù)組
C語(yǔ)言中的動(dòng)態(tài)數(shù)組允許元素的數(shù)量根據(jù)需要增長(zhǎng)。C動(dòng)態(tài)數(shù)組在計(jì)算機(jī)科學(xué)算法中有著廣泛的應(yīng)用。
在下面的程序中,我們?cè)贑中創(chuàng)建了一個(gè)動(dòng)態(tài)數(shù)組并調(diào)整了其大小。
#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動(dòng)態(tài)數(shù)組程序在屏幕上的結(jié)果:
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
摘要
我們可以通過(guò)根據(jù)需要在堆中創(chuàng)建內(nèi)存塊來(lái)動(dòng)態(tài)管理內(nèi)存。
在C動(dòng)態(tài)內(nèi)存分配中,內(nèi)存是在運(yùn)行時(shí)分配的。
動(dòng)態(tài)內(nèi)存分配允許操作大小靈活且可以在程序中隨時(shí)更改的字符串和數(shù)組。
當(dāng)您不知道某個(gè)特定結(jié)構(gòu)要占用多少內(nèi)存時(shí),就需要這樣做。
C語(yǔ)言中的Malloc()是動(dòng)態(tài)內(nèi)存分配函數(shù),代表內(nèi)存分配,該內(nèi)存分配將具有特定大小的內(nèi)存塊初始化為垃圾值。
C中的Calloc()是一個(gè)連續(xù)的內(nèi)存分配函數(shù),該函數(shù)一次將多個(gè)內(nèi)存塊初始化為0。
C語(yǔ)言中的Realloc()用于根據(jù)指定的大小重新分配內(nèi)存。
Free()函數(shù)用于清除動(dòng)態(tài)分配的內(nèi)存。
作者介紹
熱門(mén)博客推薦