記憶體管理GetMemory

2021-08-29 03:49:54 字數 4183 閱讀 3818

程式的區域性變數存在於(棧)中

程式的全域性變數存在於(靜態儲存區)中

程式動態申請的資料存在於(堆)中

在c語言下究竟如何實現動態記憶體分配 malloc(), calloc(), realloc(), 在使用這些函式時必須包含其標頭檔案,分別為:、、,而釋放記憶體的函式為free(),分別**他們的異同。

1.malloc 函式 void *malloc( unsigned int size);

在記憶體的動態儲存區中分配一塊長度為"size" 位元組的連續區域。

如果分配成功,則返回所分配記憶體空間的首位址,否則返回null,申請的記憶體不會進行初始化。

「型別說明符」表示把該區域用於何種資料型別。(型別說明符*)表示把返回值強制轉換為該型別指標。例如: pc=(char *) malloc (100);

2.calloc 函式 void *calloc(unsigned int num, unsigned int size)

按照所給的資料個數和資料型別所佔位元組數,分配乙個 num * size 連續的空間。 函式返回該儲存區的起始位址。

calloc申請記憶體空間後,會自動初始化記憶體空間為 0,但是malloc不會進行初始化,其記憶體空間儲存的是一些隨機資料。

calloc函式與malloc 函式的區別僅在於一次可以分配n塊區域。例如: ps=(struct stu*) calloc(2,sizeof (struct stu)); 其中的sizeof(struct stu)是求stu的結構長度。

3. realloc函式:void *realloc(void *ptr, unsigned int size)

動態分配乙個長度為size的記憶體空間,並把記憶體空間的首位址賦值給ptr,把ptr記憶體空間調整為size。

申請的記憶體空間不會進行初始化。

例如p1=(float *)realloc(p1,16);將原先開闢的8個位元組調整為16個位元組。

4. free函式: 函式原型為void free(void *ptr)

例如free((void *)p1);將上例開闢的16個位元組釋放。可簡寫為free(p1);由系統自動進行型別轉換。

在c++中,記憶體分成5個區,他們分別是堆、棧、自由儲存區、全域性/靜態儲存區和常量儲存區。

申請和釋放堆中分配的儲存空間,分別使用new 和 delete的兩個運算子來完成:

指標變數名 = new 型別名(初始化式);

delete 指標名;

例如:int *pi = new int(0)

malloc與free是c++/c語言的標準庫函式,new/delete是c++的運算子。它們都可以用於申請動態記憶體和釋放記憶體。

對於非內部資料型別物件而言,光用malloc/free無法滿足動態物件的要求。物件在建立的同時要自動執行建構函式,物件在消亡之前要自動執行析構函式。由於malloc/free是庫函式而不是運算子,不在編譯器控制許可權之內,不能夠把執行建構函式和析構函式的任務強加於malloc/free.

1. 申請單個物件

int *p;

p=new int;或者 p=new int(value);

2. 動態申請陣列

int *p;

p=new int [100];

這樣可以申請長度為100的陣列,但是不能進行初始化。

3. delete

int *p, *q;

p=new int;

q=new int[10];

delete p;

delete [ ]q;

題目1:

void

getmemory

(char

*p)void

test1

(void

)

請問執行tes1t函式會有什麼樣的結果?

答:試題傳入getmemory( char *p )函式的形參為字串指標,在函式內部修改形參並不能真正的改變傳入形參的值,執行完

char *str = null;

getmemory( str );

後的str仍然為null;

毛病出在函式getmemory 中。編譯器總是要為函式的每個引數製作臨時副本,指標引數p的副本是 _p,編譯器使 _p = p。如果函式體內的程式修改了_p的內容,就導致引數p的內容作相應的修改。這就是指標可以用作輸出引數的原因。在本例中,_p申請了新的記憶體,只是把 _p所指的記憶體位址改變了,但是p絲毫未變。所以函式getmemory並不能輸出任何東西。事實上,每執行一次getmemory就會洩露一塊記憶體,因為沒有用free釋放記憶體。

題目2:

char

*getmemory

(void

)void

test2

(void

)

請問執行test2函式會有什麼樣的結果?

答:可能是亂碼。

char p = 「hello world」;

return p;

p陣列為函式內的區域性自動變數,在函式返回後,記憶體已經被釋放。這是許多程式設計師常犯的錯誤,其根源在於不理解變數的生存期。

題目3:

char

*getmemory3

(void

)void

test3

(void

)

test3 中列印hello world,因為返回常量區,而且並沒有被修改過。

題目4:

void

getmemory2

(char

**p,

int num)

void

test

(void

)

請問執行test函式會有什麼樣的結果?

答:(1)能夠輸出hello

(2)test函式中也未對malloc的記憶體進行釋放。

(3)getmemory避免了試題1的問題,傳入getmemory的引數為字串指標的指標,但是在getmemory中執行申請記憶體及賦值語句

*p = (char *) malloc( num );

後未判斷記憶體是否申請成功,應加上:

if ( *p == null )

&str是指標的位址,將指標的位址傳給形參p,則p也指向str,所以 *p = (char *)malloc(sizeof(char) * num);也就是給p所指向的str分配了記憶體,所以正確。

題目5:

void

test

(void

)}

請問執行test函式會有什麼樣的結果?

答:執行

char *str = (char *) malloc(100);

後未進行記憶體是否申請成功的判斷;另外,在free(str)後未置str為空,導致可能變成乙個「野」指標,應加上:

str = null;

題目6:

void

test6()

}

//vc斷言失敗,執行錯誤

題目7:

char

*getstring

(void

)void

test4

(void

)

不要用return語句返回指向「棧記憶體」的指標,因為該內存在函式結束時自動消亡;

題目8:

char

*getstring2

(void

)void

test5

(void

)

函式test5執行雖然不會出錯,但是函式getstring2的設計概念卻是錯誤的。因為getstring2內的「hello world」是常量字串,位於靜態儲存區,它在程式生命期內恆定不變。無論什麼時候呼叫getstring2,它返回的始終是同乙個「唯讀」的記憶體塊。

題目9:

void

test

(void

)}

題目11:

char

*getmemory3

(int num)

void

test3

(void

)

正確

Getmemory的幾個經典的關於記憶體的筆試題

面試c 程式設計師時用得著的幾道題 getmemory的幾個經典的關於記憶體的筆試題 void getmemory1 char p void test1 void str一直是空,程式崩潰 char getmemory2 void void test2 void char getmemory3 vo...

GetMemory函式詳解

include include include using namespace std char getmemory char p,int num int main void getmemory錯誤講解 指標練習 錯誤程式 void getmemory char p void test void 這...

GetMemory函式詳解

void getmemory char p void test 實質 getmemory str 在呼叫時會生成乙個 str與str指向同乙個數,這是因為c語言中函式傳遞形參不改變實參的內容,但是指標指向的內容是相同的,因此可以用指標控制資料。題中的getmemory str 實質是對 str的操作...