欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C語言動(dòng)態(tài)內(nèi)存的分配實(shí)例詳解

 更新時(shí)間:2022年06月14日 14:57:24   作者:誠摯的喬治  
動(dòng)態(tài)內(nèi)存管理同時(shí)還具有一個(gè)優(yōu)點(diǎn),當(dāng)程序在具有更多內(nèi)存的系統(tǒng)上需要處理更多數(shù)據(jù)時(shí),不需要重寫程序,下面這篇文章主要給大家介紹了關(guān)于C語言動(dòng)態(tài)內(nèi)存分配的相關(guān)資料,需要的朋友可以參考下

前言

給數(shù)組分配多大的空間?

你是否和初學(xué)C時(shí)的我一樣,有過這樣的疑問。

這一期博客就來聊一聊動(dòng)態(tài)內(nèi)存的分配

讀完這篇文章,你可能對內(nèi)存的分配有一個(gè)更好的理解

??動(dòng)態(tài)內(nèi)存分配的定義

首先我們要搞清楚什么是動(dòng)態(tài)內(nèi)存的分配

平常我們定義的數(shù)組,都是在棧區(qū)分配的空間,都是分配的空間都是固定的大小

這種分配固定大小的內(nèi)存分配方法稱之為靜態(tài)內(nèi)存分配

與靜態(tài)內(nèi)存相對的,就是可以控制內(nèi)存的分配的動(dòng)態(tài)內(nèi)存分配

??注意:這里動(dòng)態(tài)內(nèi)存分配的空間是在堆區(qū)申請的,不是在棧區(qū)申請的

??這里要講一下什么是棧區(qū),什么是堆區(qū)

內(nèi)存的空間并不是都是一樣的,在學(xué)習(xí)C語言時(shí),提到的區(qū)域大致上分為棧區(qū),堆區(qū),和靜態(tài)區(qū)。就比如說在一個(gè)車間一樣,不同的區(qū)域做著不同的事,就有不同的功能,但是這些不同的功能又不是毫不相關(guān)的,他們彼此聯(lián)系,相互構(gòu)成整個(gè)內(nèi)存空間.

??動(dòng)態(tài)內(nèi)存的優(yōu)勢

<1>  可以控制內(nèi)存的大小

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

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

在動(dòng)態(tài)內(nèi)存分配就可以避免這個(gè)問題,你可以運(yùn)用 reallac 控制大小,當(dāng)內(nèi)存達(dá)到申請的空間時(shí),就會主動(dòng)擴(kuò)容,也就是再次向內(nèi)存申請空間。

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

靜態(tài)內(nèi)存分配利用的空間,整個(gè)程序結(jié)束才會釋放給系統(tǒng)

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

<3>不占用棧區(qū)的內(nèi)存

假設(shè)棧區(qū)定義了變量

而每個(gè)變量分配內(nèi)存時(shí),之間又有一定的間隙

當(dāng)定義的變量足夠多時(shí),空隙也會很多

這時(shí)候向系統(tǒng)申請一個(gè)比較大且連續(xù)的空間時(shí),雖然有足夠的空間,但是缺少了連續(xù)的空間

就無法申請到這部分空間

所以動(dòng)態(tài)內(nèi)存在堆區(qū)申請,就完全不必?fù)?dān)心棧區(qū)的空間不夠的問題

說到這里,你是不是有一個(gè)疑惑,為什么空間的內(nèi)存存在棧區(qū)和堆區(qū)之分 

如果感興趣,可以參考這個(gè)回答——為什么存在棧區(qū)堆區(qū)

??malloc calloc realloc和free函數(shù)的介紹

在動(dòng)態(tài)內(nèi)存的分配中,離不開malloc與calloc,這兩個(gè)函數(shù)都是向內(nèi)存申請空間

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

這兩個(gè)函數(shù)都是向系統(tǒng)申請動(dòng)態(tài)內(nèi)存空間,他們的頭文件,返回值和功能大致都是相同的

不同的是calloc函數(shù)開辟的空間,就會將空間的內(nèi)容全部初始話為零

而,malloc函數(shù)向系統(tǒng)申請的空間,空間的值都是隨機(jī)的

                realloc

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

??動(dòng)態(tài)空間的申請與釋放

講完動(dòng)態(tài)內(nèi)存申請的相關(guān)函數(shù),那具體的代碼實(shí)現(xiàn)是什么呢

<1>    double *x;

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

<3>    free;

 下面動(dòng)態(tài)分配的內(nèi)存賦值并顯示

??為單個(gè)對象分配空間

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

?? 為數(shù)組分配空間

#include<stdio.h>
#include<stdlib.h>
int main()//動(dòng)態(tài)內(nèi)存的賦值與顯示
{
	int n = 0;  int* a; int i = 0;
	printf("輸入分配空間元素的個(gè)數(shù):>");
	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;
}

這里其實(shí)沒有“為數(shù)組開辟的空間”這一說

因?yàn)閯?dòng)態(tài)申請的空間都是一個(gè)一個(gè)的“

不難發(fā)現(xiàn),calloc與malloc的差別并不大,只有第一個(gè)參數(shù)不同

在這兩行代碼中,存在著一個(gè)小細(xì)節(jié) 

a = malloc(sizeof(int));

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

這兩者的差別不僅僅是函數(shù)的不同,其中后者有強(qiáng)制類型轉(zhuǎn)換,而前者沒有

實(shí)際上在C語言的標(biāo)準(zhǔn)上,有無強(qiáng)制類型轉(zhuǎn)換都是行得通的(當(dāng)然在c++必須將強(qiáng)制類型轉(zhuǎn)換)

因?yàn)闊o論是calloc還是malloc,他們的返回值都是void* ,這里的void*實(shí)際上可以轉(zhuǎn)換為int*類型或者其他類型,換句話說,就是返回的指針是兼容所有類型的萬能指針。

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

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

??改變申請的動(dòng)態(tài)內(nèi)存(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));
		}
	//需要擴(kuò)容
		int* ret = realloc(a, 80);
		if (ret != NULL)
		{
			a = ret;
		}
		free(a);
        a=NULL;
	}
}

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

??擴(kuò)容可能有三種情況

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

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

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

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

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

第三種就擴(kuò)容失敗,就會導(dǎo)致擴(kuò)容前申請的空間,也發(fā)生了改變,所以不能直接用a來重新賦值,

總結(jié)

到此這篇關(guān)于C語言動(dòng)態(tài)內(nèi)存分配的文章就介紹到這了,更多相關(guān)C語言動(dòng)態(tài)內(nèi)存分配內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C語言代碼鏈表實(shí)現(xiàn)貪吃蛇游戲

    C語言代碼鏈表實(shí)現(xiàn)貪吃蛇游戲

    這篇文章主要為大家詳細(xì)介紹了C語言鏈表實(shí)現(xiàn)貪吃蛇游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-01-01
  • 詳解Matlab如何繪制?;鶊D

    詳解Matlab如何繪制?;鶊D

    桑基圖是一種特定類型的流程圖,圖中延伸的分支的寬度對應(yīng)數(shù)據(jù)流量的大小,通常應(yīng)用于能源、材料成分、金融等數(shù)據(jù)的可視化分析。本文將用Matlab繪制好看的桑基圖,需要的可以參考一下
    2022-03-03
  • 利用Matlab實(shí)現(xiàn)迭代適應(yīng)點(diǎn)算法

    利用Matlab實(shí)現(xiàn)迭代適應(yīng)點(diǎn)算法

    道格拉斯-普克算法(Douglas–Peucker?algorithm,亦稱為拉默-道格拉斯-普克算法、迭代適應(yīng)點(diǎn)算法、分裂與合并算法)是將曲線近似表示為一系列點(diǎn),并減少點(diǎn)的數(shù)量的一種算法。本文將利用Matlab實(shí)現(xiàn)這一算法,需要的可以參考一下
    2022-04-04
  • C語言實(shí)現(xiàn)簡單通訊錄系統(tǒng)

    C語言實(shí)現(xiàn)簡單通訊錄系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了C語言實(shí)現(xiàn)簡單通訊錄系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-07-07
  • C語言實(shí)現(xiàn)UDP通信

    C語言實(shí)現(xiàn)UDP通信

    這篇文章主要為大家詳細(xì)介紹了C語言實(shí)現(xiàn)UDP通信,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-06-06
  • C++ string和wstring相互轉(zhuǎn)換方式

    C++ string和wstring相互轉(zhuǎn)換方式

    這篇文章主要介紹了C++ string和wstring相互轉(zhuǎn)換方式,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-02-02
  • C++編程中的或||、與&&、非!邏輯運(yùn)算符基本用法整理

    C++編程中的或||、與&&、非!邏輯運(yùn)算符基本用法整理

    這篇文章主要介紹了C++中的或||、與&&、非!邏輯運(yùn)算符基本用法整理,是C++入門學(xué)習(xí)中的基礎(chǔ)知識,需要的朋友可以參考下
    2016-01-01
  • C++ explicit關(guān)鍵字講解

    C++ explicit關(guān)鍵字講解

    這篇文章主要介紹了C++ explicit關(guān)鍵字講解,++提供了explicit關(guān)鍵字,相對于implicit而言,他默認(rèn)關(guān)閉了隱式類型轉(zhuǎn)換方法。至于兩者有什么區(qū)別,看下面文章內(nèi)容的介紹吧
    2021-12-12
  • C語言開發(fā)之歸并排序詳解及實(shí)例

    C語言開發(fā)之歸并排序詳解及實(shí)例

    這篇文章主要介紹了 C語言開發(fā)之歸并排序詳解及實(shí)例的相關(guān)資料,需要的朋友可以參考下
    2017-03-03
  • C語言學(xué)生成績管理系統(tǒng)課程設(shè)計(jì)

    C語言學(xué)生成績管理系統(tǒng)課程設(shè)計(jì)

    這篇文章主要為大家詳細(xì)介紹了C語言學(xué)生成績管理系統(tǒng)課程設(shè)計(jì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-01-01

最新評論