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

關(guān)于C語言動(dòng)態(tài)內(nèi)存管理介紹

 更新時(shí)間:2022年01月27日 15:28:19   作者:invictusQAQ  
大家好,本篇文章主要講的是關(guān)于C語言動(dòng)態(tài)內(nèi)存管理介紹,感興趣的同學(xué)趕快來看一看吧,對(duì)你有幫助的話記得收藏一下

1.為什么需要?jiǎng)討B(tài)內(nèi)存分配

關(guān)于這個(gè)問題,我們先看看我們之前是如何開辟內(nèi)存的。

int val = 20;//在??臻g上開辟四個(gè)字節(jié)
char arr[10] = {0};//在??臻g上開辟10個(gè)字節(jié)的連續(xù)空間

但可以發(fā)現(xiàn)的一個(gè)問題是,無論我們?cè)鯓娱_辟內(nèi)存空間,他的大小都在開辟前就已經(jīng)被指定,而顯然在實(shí)際應(yīng)用中并不是所有情況我們都能在程序編譯前就知道他需要多大的內(nèi)存空間?;蛟S你想說那有備無患開大點(diǎn)不久好了?但這樣所造成的空間浪費(fèi)并不是我們所希望看到的結(jié)果。于是我們就只能試試動(dòng)態(tài)內(nèi)存分配了。

2.有關(guān)動(dòng)態(tài)內(nèi)存函數(shù)介紹

2.1 malloc和free

c語言已經(jīng)為我們提供了一個(gè)動(dòng)態(tài)內(nèi)存開辟的函數(shù)malloc

void* malloc (size_t size);

1.這個(gè)函數(shù)向內(nèi)存申請(qǐng)一塊連續(xù)可用的空間,并返回指向這塊空間的指針。

2.如果開辟成功,則返回一個(gè)指向開辟好空間的指針。

3.如果開辟失敗,則返回一個(gè)NULL指針,因此malloc的返回值一定要做檢查。

4.返回值的類型是 void* ,所以malloc函數(shù)并不知道開辟空間的類型,具體在使用的時(shí)候使用者自 己來決定。

5.如果參數(shù) size 為0,malloc的行為是標(biāo)準(zhǔn)是未定義的,取決于編譯器。

當(dāng)然有分配就會(huì)有釋放,c語言也為我們提供了另一個(gè)函數(shù)free,專門用來做動(dòng)態(tài)內(nèi)存的釋放以及回收,函數(shù)原型如下。

void free (void* ptr);

1.free函數(shù)用來釋放動(dòng)態(tài)開辟的內(nèi)存。

2.如果參數(shù) ptr 指向的空間不是動(dòng)態(tài)開辟的,那free函數(shù)的行為是未定義的。

3.如果參數(shù) ptr 是NULL指針,則函數(shù)什么事都不做。

我們看到下面的一個(gè)例子

#include <stdio.h>
int main()
{
	int* ptr = NULL;
	ptr = (int*)malloc(num * sizeof(int));
	if (NULL != ptr)//判斷ptr指針是否為空
	{
		int i = 0;
		for (i = 0; i < num; i++)
		{
			*(ptr + i) = 0;
		}
	}
	free(ptr);//釋放ptr所指向的動(dòng)態(tài)內(nèi)存
	ptr = NULL;
	return 0;
}

相信這串代碼大家在有注釋的情況下都能夠看懂。但是有細(xì)心的讀者可能會(huì)發(fā)現(xiàn)free(ptr)之后又令ptr=NULL,這是為什么呢?其實(shí)在一塊內(nèi)存空間被釋放后,該指針仍指向被釋放掉的內(nèi)存地址,而此時(shí)的ptr便成了野指針,一旦后續(xù)不小心被程序調(diào)用就會(huì)導(dǎo)致程序崩潰,所以在指針釋放后要將其置為NULL防止這種情況的發(fā)生。

2.2 calloc函數(shù)

calloc函數(shù)類似與malloc,同樣用于動(dòng)態(tài)內(nèi)存分配,函數(shù)原型如下。

void* calloc (size_t num, size_t size);

函數(shù)的功能是為 num個(gè)大小為size的元素開辟一塊空間,并且把空間的每個(gè)字節(jié)初始化為0。

與函數(shù)malloc的區(qū)別只在于calloc會(huì)在返回地址之前把申請(qǐng)的空間的每個(gè)字節(jié)初始化為全0。

2.3 realloc函數(shù)

有時(shí)會(huì)我們發(fā)現(xiàn)過去申請(qǐng)的空間太小了,有時(shí)候我們又會(huì)覺得申請(qǐng)的空間過大了,那為了合理的時(shí) 候內(nèi)存,我們一定會(huì)對(duì)內(nèi)存的大小做靈活的調(diào)整。那 realloc 函數(shù)就可以做到對(duì)動(dòng)態(tài)開辟內(nèi)存大 小的調(diào)整。函數(shù)原型如下。

void* realloc (void* ptr, size_t size);

ptr 是要調(diào)整的內(nèi)存地址

size 調(diào)整之后新大小

返回值為調(diào)整之后的內(nèi)存起始位置。

這個(gè)函數(shù)調(diào)整原內(nèi)存空間大小的基礎(chǔ)上,還會(huì)將原來內(nèi)存中的數(shù)據(jù)移動(dòng)到新的空間。

需要注意的是:

realloc在調(diào)整內(nèi)存空間時(shí)存在兩種情況

情況1:原有空間之后有足夠大的空間

情況2:原有空間之后沒有足夠大的空間

參見下圖示意

 情況1

當(dāng)是情況1的時(shí)候,要擴(kuò)展內(nèi)存就直接原有內(nèi)存之后直接追加空間,原來空間的數(shù)據(jù)不發(fā)生變化。

情況2

當(dāng)是情況2 的時(shí)候,原有空間之后沒有足夠多的空間時(shí),擴(kuò)展的方法是:在堆空間上另找一個(gè)合適大小 的連續(xù)空間來使用。這樣函數(shù)返回的是一個(gè)新的內(nèi)存地址。

針對(duì)情況二,若realloc成功,指向原內(nèi)存地址的指針就成了懸掛指針,即指針指向了一塊沒有分配給用戶使用的內(nèi)存,如果再使用該指針進(jìn)行操作就可能發(fā)生意想不到的情況,因此要格外注意這種情況。

#include <stdio.h>
int main()
{
	int* ptr = (int*)malloc(100);//動(dòng)態(tài)分配
	int* p = NULL;
	p = (int*)realloc(ptr, 1000);//重分配
	if (p != NULL)//判斷是否成功
	{
		ptr = p;//防止懸掛指針出現(xiàn)
	}
	//業(yè)務(wù)處理
	free(ptr);
    ptr=NULL;//釋放后置空防止野指針
	return 0;
}

注意動(dòng)態(tài)內(nèi)存分配時(shí)應(yīng)當(dāng)像上述代碼一樣盡量規(guī)范。

3. 常見的動(dòng)態(tài)內(nèi)存錯(cuò)誤

3.1 對(duì)NULL指針進(jìn)行解引用操作

這個(gè)點(diǎn)就不再過多敘述,大家記住即可,對(duì)空指針進(jìn)行解引用操作可能會(huì)引發(fā)各種奇怪的問題。

3.2 對(duì)動(dòng)態(tài)開辟空間的越界訪問

同數(shù)組類似,即使是動(dòng)態(tài)開辟的空間也不能越界訪問。

3.3 對(duì)非動(dòng)態(tài)開辟內(nèi)存使用free釋放

切記只有動(dòng)態(tài)開辟的內(nèi)存才能使用free。

3.4 使用free釋放一塊動(dòng)態(tài)開辟內(nèi)存的一部分

參見下面代碼

void test()
{
 int *p = (int *)malloc(100);
 p++;
 free(p);//p不再指向動(dòng)態(tài)內(nèi)存的起始位置
}

雖然有些小伙伴可能想既然free函數(shù)是根據(jù)指針來釋放內(nèi)存的,那我能不能通過對(duì)指針進(jìn)行操作去部分釋放動(dòng)態(tài)分配的內(nèi)存呢?然而夢(mèng)想很美好,現(xiàn)實(shí)很骨感。如果強(qiáng)行這樣做的話只可能會(huì)造成·更多不可預(yù)估的結(jié)果。

3.5 對(duì)同一塊動(dòng)態(tài)內(nèi)存多次釋放

這個(gè)錯(cuò)誤應(yīng)該大家目前應(yīng)該不太常犯,但是一旦后面代碼量大了之后就很有可能忘記是否已經(jīng)釋放過內(nèi)存從而導(dǎo)致重復(fù)釋放而bug。

3.6 動(dòng)態(tài)開辟內(nèi)存忘記釋放(內(nèi)存泄漏)

void test()
{
 int *p = (int *)malloc(100);
 if(NULL != p)
 {
 *p = 20;
 }
}
int main()
{
 test();
 while(1);
}

看到這個(gè)標(biāo)題再看這串代碼,大家應(yīng)該都很容易能夠知道上面的代碼忘記釋放內(nèi)存了從而導(dǎo)致內(nèi)存泄漏,但實(shí)際日常我們非常容易忘記開辟內(nèi)存后free。

忘記釋放不再使用的動(dòng)態(tài)開辟的空間會(huì)造成內(nèi)存泄漏。

切記:

動(dòng)態(tài)開辟的空間一定要釋放,并且正確釋放 。

總結(jié)

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

相關(guān)文章

  • c語言獲取文件大小的示例

    c語言獲取文件大小的示例

    在C語言中測試文件的大小,主要使用二個(gè)標(biāo)準(zhǔn)函數(shù),下面是使用示例,需要的朋友可以參考下
    2014-02-02
  • 關(guān)于C++中0是十進(jìn)制還是八進(jìn)制的問題

    關(guān)于C++中0是十進(jìn)制還是八進(jìn)制的問題

    本篇文章中,小編將為大家介紹關(guān)于C++中0是十進(jìn)制還是八進(jìn)制的問題,有需要的朋友可以參考一下
    2013-04-04
  • C++與Lua交互內(nèi)存分配詳解

    C++與Lua交互內(nèi)存分配詳解

    C/C++ 與 Lua 的交互是通過 lua_State 這一句柄進(jìn)行交互,我們常規(guī)的創(chuàng)建都是通過 luaL_newstate 這一輔助函數(shù),這篇文章主要給大家詳細(xì)介紹了C++與Lua交互內(nèi)存分配,文中有相關(guān)的代碼示例供大家參考,需要的朋友可以參考下
    2023-11-11
  • 一文教你Qt如何操作SQLite數(shù)據(jù)庫

    一文教你Qt如何操作SQLite數(shù)據(jù)庫

    Sqlite 數(shù)據(jù)庫作為 Qt 項(xiàng)目開發(fā)中經(jīng)常使用的一個(gè)輕量級(jí)的數(shù)據(jù)庫,可以說是兼容性相對(duì)比較好的數(shù)據(jù)庫之一。本文為大家介紹了Qt操作SQLite數(shù)據(jù)庫的具體方法,希望對(duì)大家有所幫助
    2023-03-03
  • C語言執(zhí)行時(shí),程序控制臺(tái)輸出窗口 一閃而過問題及解決

    C語言執(zhí)行時(shí),程序控制臺(tái)輸出窗口 一閃而過問題及解決

    這篇文章主要介紹了C語言執(zhí)行時(shí),程序控制臺(tái)輸出窗口 一閃而過問題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-11-11
  • C++中整形與浮點(diǎn)型如何在內(nèi)存中的存儲(chǔ)詳解

    C++中整形與浮點(diǎn)型如何在內(nèi)存中的存儲(chǔ)詳解

    大家好!這期和大家分享整形和浮點(diǎn)型是如何在數(shù)據(jù)是如何在內(nèi)存中存儲(chǔ),下面文章具有一定的參考價(jià)值,需要的小伙伴可以參考一下
    2022-05-05
  • C++的輸入和輸出流詳解

    C++的輸入和輸出流詳解

    這篇文章主要為大家詳細(xì)介紹了C++的輸入和輸出流,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-03-03
  • C語言 typedef:給類型起一個(gè)別名

    C語言 typedef:給類型起一個(gè)別名

    本文主要介紹C語言 typedef,這里整理了相關(guān)資料及簡單示例代碼幫助大家學(xué)習(xí)理解,有興趣的小伙伴可以參考下
    2016-08-08
  • C++使用泛型導(dǎo)致的膨脹問題

    C++使用泛型導(dǎo)致的膨脹問題

    這篇文章主要介紹了C++使用泛型導(dǎo)致的膨脹,智能家居主機(jī)的嵌入式平臺(tái)上使用C++進(jìn)行開發(fā)。FLASH存儲(chǔ)空間有限,這是必須要考慮的因素,一定要重視,下面我們一起進(jìn)入文章看看詳細(xì)內(nèi)容
    2021-11-11
  • C++簡單五子棋的AI設(shè)計(jì)實(shí)現(xiàn)

    C++簡單五子棋的AI設(shè)計(jì)實(shí)現(xiàn)

    這篇文章主要為大家詳細(xì)介紹了C++簡單五子棋的AI設(shè)計(jì)實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-09-09

最新評(píng)論