C語言中堆記憶體的開闢和釋放與記憶體處理函式

2022-09-01 13:06:13 字數 3907 閱讀 5743

c語言動態分配記憶體,malloc的出現就是來彌補靜態記憶體分配的缺點

比如說我們在定義陣列的時候,陣列的長度必須是乙個常量,不能改變的值,假如我事先定義了陣列,一旦業務需求發生改變,那麼這個陣列就不能再使用了。

傳統的陣列定義也就是靜態分配,是不能夠手動釋放的,只能等待系統釋放,靜態分配的記憶體,是分配在棧中的,c語言中的函式呼叫也是通過棧來實現的,棧有乙個特點就是先進後出,在呼叫函式的時候,是先壓入棧,然後從最上面的函式開始執行

我們先來看看記憶體四區,分別為堆區,棧區,資料區,**區,對於這四個區,做了以下總結

**區:

程式執行二進位製碼(程式指令)

共享,唯讀

資料區 :

初始化資料區(data)

未初始化資料區(bss)

常量區棧區 :

系統為每乙個程式分配乙個臨時的空間,

區域性變數,函式資訊,函式引數,陣列

棧區大小為:1m

在windows中可以擴充套件到10m

在linux中可以擴充套件到16m

堆區 :

棧區大小為:1m,我們來驗證一下

int zhan[8200000] = ;

在c語言中,我們定義了乙個陣列,長度為820000,那麼我們知道,在棧中我們最多可分配1m的記憶體,我們可以計算一下,這八百二十萬的長度佔了多大的記憶體,

定義的是int型別,所以8200000*4=32800000(位元組)

得到的結果再除以1024,32800000/1024=32031.25(kb)

得到的結果再除以1024,32031.25/1024=31.280517578125(m)

大約是31m,最終執行起來,這個程式是會報錯的。

接下來我們就開闢堆記憶體儲存資料,這就用到了函式malloc

動態分配記憶體函式

malloc

使用函式之前我們要引用標頭檔案stdlib.h

#include

malloc函式語法示例

int* p1 = (int*)malloc(sizeof(int))

返回值型別為void* 型別,也就是指標型別,int* p1代表乙個以int型別位址為內容的指標變數

int型別在記憶體中占用的大小為 4位元組。

malloc括號中就是你要開闢的空間大小,單位是位元組,分配一塊連續的區域

假如我要開闢乙個空間,裡面儲存5個數字,那麼**如下

int* p1 = (int*)malloc(sizeof(int)*5);

這樣的格式可以更容易的理解,當然你也可以像下面這麼寫

int* p1 = (int*)malloc(20);

如果位址開闢成功,返回乙個記憶體位址,否則返回null,需要注意的是,如果開闢失敗了,那麼在後邊的程式中呼叫,程式就會報錯,所以有時候還要加乙個判斷條件,這點要注意

if (p1 ==null)

成功以後,我們可以使用這個記憶體空間,對它進行賦值。

在使用完之後,也可以呼叫free函式釋放,**如下

free(p1);

那麼,當我們釋放這個p1之後,這個記憶體空間還能呼叫嗎?其實還可以呼叫的。在釋放之後,這個記憶體位址就變成了乙個野指標,還可以進行賦值

為了避免野指標,在free(p1)後在加上一段**

p1 = null;

賦值為null,這個是可有可無的。

我們再來看乙個函式,叫做記憶體操作函式

memset(),memcpy(),memmove(),

引用 string.h

#include

1.memset()引數,  

void*memset(void*s,intc,size_tn);

我們來看看它的示例

int* p = (int*)malloc(sizeof(int) * 10

);memset(p,

0, 40);

傳入p這個記憶體位址,重置為0,位元組為40位元組

它在重置為0時有效,並不是真正意義上的重置

這個函式作用通常是一串連續的記憶體一起操作,不會單獨對變數進行操作。

2.memcpy(),引數,void*memcpy(void*dest,constvoid*src,size_tn);

示例:

int arr = ;

int* p = (int*)malloc(sizeof(int) * 9

); memcpy(p, arr,

sizeof(int) * 9);

arr存在棧記憶體中,p存在堆記憶體中,我們現在要把arr中的數複製到p中,這就用到了  memcpy()函式

用法:memcpy(新資料,源資料,記憶體大小(位元組))

它不同於strcpy()這個函式,strcpy()是字串拷貝遇到\0會停止,而memcpy()拷貝的是記憶體,拷貝的內容和位元組有關。

如果引數1和引數2的記憶體位址重疊,可能會導致程式報錯,應盡量避免

3.memmove()

memmove()功能用法和memcpy()一樣,區別在於:dest和src所指的記憶體空間重疊時,memmove()仍然能處理,不過執行效率比memcpy()低些。

4.memcmp(),引數,intmemcmp(constvoid*s1,constvoid*s2,size_tn);

int arr = ;

int arry = ;

int value = memcmp(arr, arry, 20);

第乙個引數和第二個引數進行比較,比較前20個位元組,也就是前5個數,如果相等返回0,否則返回-1;

同樣可以比較字串,**如下:

char arr = "

hello\0 word";

char arry = "

hello\0 word";

int value = memcmp(arr, arry, 11);

c 記憶體的開闢和釋放

關於new和delete,malloc和free。我們都知道,是在不同的語言裡面做相應的記憶體的開闢和釋放工作的,那麼這篇博文就來好好的了解一下他們的區別和工作原理吧 1 引言 首先,我們還是寫乙個我們經常使用的在c語言中動態開闢的方式 int main p 10 free p return0 其中...

記憶體的動態開闢與釋放

malloc free與new delete 1 new會拋異常,但是malloc不會拋異常 2 new delete屬於操作符,但是malloc free屬於函式 3 new申請空間的時候會呼叫建構函式進行初始化,malloc不會 delete釋放記憶體時會呼叫析構函式,free只是切斷了指向關係...

C語言中的記憶體分配與釋放

對c語言一直都是抱著學習的態度,很多都不懂,今天突然被問道c語言的記憶體分配問題,說了一些自己知道的,但感覺回答的並不完善,所以才有這篇筆記,總結一下c語言中記憶體分配的主要內容。剛剛在一篇博文看到乙個簡單的問題 code1 char tostr intmain code2 char tostr i...