c c 動態記憶體總結

2022-09-02 06:00:11 字數 3353 閱讀 9815

c動態記憶體分配:malloc / realloc / calloc

malloc的引數是使用者所需記憶體空間大小的位元組數,不會對申請成功的記憶體初始化。

malloc 申請空間時並不是需要多少就申請多少,而是會多申請一些空間:

a.多申請乙個32位元組的結構體,裡面對申請的空間進行描述,

b.在申請的空間前後會各多申請 4 個位元組的空間,這就是保護機制,當你操作不當越界了,這 8 個位元組的內容會改變,作業系統會檢查前後 4 個位元組是否改變了,以此判斷是否越界了

calloc的引數:第乙個:元素的個數,第二個:單個元素所佔位元組;會把申請成功的空間初始化為 0

realloc的引數:第乙個:位址,第二個:位元組數

對於 realloc 的第乙個引數:

如果指向空,那麼此時realloc 就和 malloc 是一樣的;

如果不為空,那麼就將即將要申請的空間與原空間進行比較。

如果要申請的空間比原空間小,就將原空間縮小,並返回原空間首位址

如果要申請的空間比原空間大,那麼分兩種情況:

第一種:新舊空間之差小於原空間大小,直接在原空間進行延伸,並返回原空間的首位址。

第二種:新舊空間之差大於原空間的大小,那麼直接開闢新空間,並將原空間的資料拷貝到新空間,並返回新空間首位址。

共同點:

都是從堆上進行動態記憶體分配

釋放記憶體都是需要使用free函式來釋放

三者的返回值都是void*

都需要強制型別轉換

都需要對申請出的空間判空(因為申請記憶體失敗會返回空)

c++動態記憶體分配:new

1、不用強制型別轉換;

2、不用對申請出來的空間進行判空;

3、可以申請時初始化這段空間。

當用new建立物件時:

new:先將物件的空間開闢成功,然後呼叫建構函式完成物件的初始化。

delete:先呼叫析構函式將物件中的資源清理,然後釋放物件占用的空間

如果對乙個內部有資源的自定義型別使用 malloc 開闢記憶體,此時呼叫 delete 進行空間的釋放,程式就會崩潰。因為 malloc 只負責開闢空間,並不會呼叫物件的建構函式對其成員變數進行初始化,那麼內部的成員變數是沒有分配空間的,當我們呼叫 delete 時,delete會先對物件進行資源清理,但是物件裡的資源 malloc 並沒有給其分配,所以我們清理的時候是非法的操作

對於內部有資源的自定義型別,使用 new 開闢的空間使用 free 釋放,會造成記憶體洩漏,因為 free 並不會呼叫析構函式清理物件的資源,因此會造成資源洩漏。

new乙個物件:

new建立類物件需要指標接收,一處初始化,多處使用

new建立類物件使用完需delete銷毀

new建立物件直接使用堆空間,而區域性不用new定義類物件則使用棧空間、

new物件指標用途廣泛,比如作為函式返回值、函式引數等

頻繁呼叫場合並不適合new,就像new申請和釋放記憶體一樣

new申請的物件,則只有呼叫到delete時再會執行析構函式,如果程式退出而沒有執行delete則會造成記憶體洩漏;

ctest* ptest = new

ctest();

delete ptest;

普通方式建立方式,使用完後不需要手動釋放,該類析構函式會自動執行;

ctest mtest;

總結用法(語法格式):

1.malloc

函式原型:

void *malloc( size_t size );

1)返回值是void*,需要強轉

2)只有乙個引數,表示使用者所需記憶體空間大小的位元組數。

3)只分配,不初始化。

int *p;

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

2.calloc

函式原型

void *calloc( size_t _count, size_t _size);

1)返回值void *,需要強轉

2)兩個引數,第乙個:元素的個數,第二個:單個元素所佔位元組

3)自動初始化為0.

int *p = (int *)calloc(20, sizeof(int)); //申請20個int型別控制項,每個大小sizeof(int);
3.realloc

函式原型

1)返回值void*,需強轉

3)主要用於對動態記憶體進行擴容。

如果指向空,那麼此時realloc 就和 malloc 是一樣的;

如果不為空,那麼就將即將要申請的空間與原空間進行比較。

如果要申請的空間比原空間小,就將原空間縮小,並返回原空間首位址

如果要申請的空間比原空間大,那麼分兩種情況:

第一種:新舊空間之差小於原空間大小,直接在原空間進行延伸,並返回原空間的首位址。

第二種:新舊空間之差大於原空間的大小,那麼直接開闢新空間,並將原空間的資料拷貝到新空間,並返回新空間首位址。

const int size = 2000;

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

)); //malloc動態申請

int *pp = (int *)realloc(p, size*sizeof(int));//擴容

(1,2,3均使用free(p);釋放記憶體)

4.new

int *p=new

int[10]; //建立乙個包含10個int的陣列

deletep;//告訴程式應釋放整個陣列,而不僅僅是指標指向的元素。

注意:如果使用new不帶方括號,則delete也不帶;如果new有方括號,則delete野應帶方括號。

int *p1=new

int;

int *p2=new

int [500

];delete

p2;delete p1;

C C 程式設計 動態記憶體

在使用陣列的時候,總有乙個問題困擾著我們 陣列應該有多大?例如編寫程式求n階行列式的值,用陣列表示行列式,需如下定義 define n 10 陣列定義時方括號內必須是常量 double a n n n n二維陣列表示二階行列式 而以下定義形式則是錯誤的 c 在codeblocks下無此問題 int ...

C C 動態記憶體管理

一 c語言中動態記憶體管理方式 c語言中使用 malloc calloc realloc free進行記憶體的管理和釋放 1.malloc動態記憶體申請 int ptest int malloc 10 sizeof int 申請記憶體的方式 free 釋放 2.calloc 該函式會將申請的記憶體空...

C C 動態記憶體管理

注意malloc free new delete new delete一定要匹配使用,否則可能出現記憶體洩漏甚至崩潰的問題小結 1 兩組函式都負責動態記憶體管理 2 malloc free是c c 標準庫的函式,而new delete是c 操作符。3 malloc free只負責動態分配空間 釋放空...