亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

C語言的動態內存如何分配

發布時間:2022-06-14 16:46:19 來源:億速云 閱讀:147 作者:iii 欄目:開發技術

今天小編給大家分享一下C語言的動態內存如何分配的相關知識點,內容詳細,邏輯清晰,相信大部分人都還太了解這方面的知識,所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來了解一下吧。

動態內存分配的定義

首先我們要搞清楚什么是動態內存的分配

平常我們定義的數組,都是在棧區分配的空間,都是分配的空間都是固定的大小

這種分配固定大小的內存分配方法稱之為靜態內存分配

與靜態內存相對的,就是可以控制內存的分配的動態內存分配

注意:這里動態內存分配的空間是在堆區申請的,不是在棧區申請的

這里要講一下什么是棧區,什么是堆區

內存的空間并不是都是一樣的,在學習C語言時,提到的區域大致上分為棧區,堆區,和靜態區。就比如說在一個車間一樣,不同的區域做著不同的事,就有不同的功能,但是這些不同的功能又不是毫不相關的,他們彼此聯系,相互構成整個內存空間.

C語言的動態內存如何分配

動態內存的優勢

<1>  可以控制內存的大小

在很多時候,我們申請的空間是未知的

就比如說通訊錄,在剛剛開始用的時候很小的空間就足夠了,但是在未來你不知道你需要存下多少個號碼,這時候就存在一個問題,你定的空間需要多少個字節,當申請的太少,就會出現存不下去的情況,如果存的空間過大,有會造成一定的浪費。 

在動態內存分配就可以避免這個問題,你可以運用 reallac 控制大小,當內存達到申請的空間時,就會主動擴容,也就是再次向內存申請空間。

<2> 可以多次利用這部分空間

靜態內存分配利用的空間,整個程序結束才會釋放給系統

而動態內存分配的空間,只能在函數運行結束后由系統自動釋放,需要用戶主動去釋放,可以通過利用完(就比如說打印元素,打印完),用戶再通過 free函數釋放 這塊申請的空間,當再次用動態內存申請空間時,就可以再次利用這塊空間,這樣也能在一定程度上,可以節省一定的空間。

<3>不占用棧區的內存

假設棧區定義了變量

而每個變量分配內存時,之間又有一定的間隙

當定義的變量足夠多時,空隙也會很多

這時候向系統申請一個比較大且連續的空間時,雖然有足夠的空間,但是缺少了連續的空間

就無法申請到這部分空間

所以動態內存在堆區申請,就完全不必擔心棧區的空間不夠的問題

說到這里,你是不是有一個疑惑,為什么空間的內存存在棧區和堆區之分 

如果感興趣,可以參考這個回答&mdash;&mdash;為什么存在棧區堆區

malloc calloc realloc和free函數的介紹

在動態內存的分配中,離不開malloc與calloc,這兩個函數都是向內存申請空間

 
                          calloc
頭文件               #include <stdlib.h> 
格式                   void *calloc(size_t num, size_t size);
功能                   為num個大小為size字節的對象分配存儲空間,該空間內的所有位都會初始化為。
返回值                若分配成功,則返回一個指向已分配的空間開頭的指針;若分配失敗,則返回空指針

這兩個函數都是向系統申請動態內存空間,他們的頭文件,返回值和功能大致都是相同的

不同的是calloc函數開辟的空間,就會將空間的內容全部初始話為零

而,malloc函數向系統申請的空間,空間的值都是隨機的

                realloc

頭文件     #include <stdlib.h>
格式         void *realloc(void *mem_address, unsigned int newsize);
功能         先判斷當前的指針是否有足夠的連續空間,如果有,擴大mem_address指向的地址,并且將                            mem_address返回,如果空間不夠,先按照newsize指定的大小分配空間,將原有數據從頭到尾拷貝                  到新分配的內存區域,而后釋放原來mem_address所指內存區域(注意:原來指針是自動釋放,不                    需要使用free),同時返回新分配的內存區域的首地址。即重新分配存儲器塊的地址。
返回值      如果重新分配成功則返回指向被分配內存的指針,否則返回空指針NULL。

動態空間的申請與釋放

講完動態內存申請的相關函數,那具體的代碼實現是什么呢

<1>    double *x;

<2>    x=calloc(1,sizeof(double))或者x=malloc(sizeof(double));

<3>    free;

C語言的動態內存如何分配

 下面動態分配的內存賦值并顯示

為單個對象分配空間

#include<stdio.h>
#include<stdlib.h>
int main()//動態內存的賦值與顯示
{
	int* a;
	a = malloc(sizeof(int));    //分配動態內存
	if (a == NULL)              //是否成功分配了儲存空間,否則返回分配失敗
		printf("分配失敗");
	else
	{
		*a = 20;
		printf("*a=%d\n", *a);
		free(a);                //釋放
	}
	return 0;
}

為數組分配空間

#include<stdio.h>
#include<stdlib.h>
int main()//動態內存的賦值與顯示
{
	int n = 0;  int* a; int i = 0;
	printf("輸入分配空間元素的個數:>");
	scanf_s("%d", &n);
	a =(int *) calloc(n,sizeof(int));
	if (a == NULL)
		printf("分配失敗");
	else
	{
		for (i = 0; i < n; i++)
		{
			*(a + i) = i;
			printf("*a=%d\n", *(a+i));
		}
		free(a);
	}
	return 0;
}

這里其實沒有“為數組開辟的空間”這一說

因為動態申請的空間都是一個一個的“

不難發現,calloc與malloc的差別并不大,只有第一個參數不同

在這兩行代碼中,存在著一個小細節 

a = malloc(sizeof(int));

a =(int *) calloc(n,sizeof(int));

這兩者的差別不僅僅是函數的不同,其中后者有強制類型轉換,而前者沒有

實際上在C語言的標準上,有無強制類型轉換都是行得通的(當然在c++必須將強制類型轉換)

因為無論是calloc還是malloc,他們的返回值都是void* ,這里的void*實際上可以轉換為int*類型或者其他類型,換句話說,就是返回的指針是兼容所有類型的萬能指針。

即指向void型的指針可以指向任意類型的對象,是一種特殊類型的指針。

指向void型的指針的值可以賦給指向任意類型的指針,反之亦可。

改變申請的動態內存(realloc的使用)

#include<stdlib.h>
#include<stdio.h>
int main()
{
	int* a; int i = 0;
	a=(int *)calloc(10,sizeof(int));
	if (a == NULL)
		printf("分配失敗");
     //使用
	else
	{
		for (i = 0; i < 10; i++)
		{
			*(a + i) = i;
			printf("*a=%d\n", *(a + i));
		}
	//需要擴容
		int* ret = realloc(a, 80);
		if (ret != NULL)
		{
			a = ret;
		}
		free(a);
        a=NULL;
	}
}

擴容不能直接就a=realloc(a, 80),需要中間引一個中間變量*ret

擴容可能有三種情況

情況一(在a的地址處,有空余的空間來擴容)

C語言的動態內存如何分配

情況二 (在a的地址處,沒有空余的空間來擴容,但是有其他的空間可存儲擴容后的空間)

C語言的動態內存如何分配

 情況三(reallo調整空間失敗)

C語言的動態內存如何分配

在這三種情況中,第一種的地址不變

第二種會在一個新的地方申請足夠大的地方,此時的地址不在是a原先的地址

第三種就擴容失敗,就會導致擴容前申請的空間,也發生了改變,所以不能直接用a來重新賦值。

以上就是“C語言的動態內存如何分配”這篇文章的所有內容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會為大家更新不同的知識,如果還想學習更多的知識,請關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

疏附县| 买车| 周宁县| 蒙阴县| 宿州市| 忻城县| 神木县| 湄潭县| 泗阳县| 两当县| 宁晋县| 潜江市| 灵石县| 五莲县| 电白县| 高州市| 温宿县| 班玛县| 新源县| 乌鲁木齐市| 南昌县| 淮南市| 松江区| 泽州县| 凤城市| 穆棱市| 彩票| 湄潭县| 郧西县| 汤原县| 磴口县| 元阳县| 安阳市| 仲巴县| 浦东新区| 法库县| 大化| 建宁县| 南江县| 榆树市| 南阳市|