1、 記憶體分配方式
(1)從靜態儲存區域分配。例如使用static、全域性變數。靜態儲存區的資料在程式編譯的時候就已經分配好了,在程式執行期間一直存在,只有在程式推出之後才會釋放。
(2)在棧上分配。函式內部的區域性變數都是在棧上分配的,在函式階數時儲存空間便被釋放;
(3)在堆上分配。程式設計師根據自己的需要申請和釋放記憶體(new/delete malloc/free)
2、在記憶體的分配過程中經常會出現一些錯誤。
(1)記憶體未分配成功卻使用了他。例如記憶體中沒有足夠大的剩餘空間此時記憶體分配(new/malloc)失敗之後會返回null,可以用assert(p!=null)或者if語句進行檢查。
(2)記憶體分配成功卻沒有初始化就引用它。 int *p=newint(10);//忘記初始化
(3)記憶體分配成功,但是越界操作。在使用陣列下標時容易出現「多1」、「少1」
(4)忘記釋放記憶體,造成記憶體洩露。
(5)記憶體被釋放(delete)之後卻繼續使用它
3、指標與陣列
(1)修改內容
char a=」hello」;
a[0]=』x』;
cout<
char *p=」world」; //這裡定義p指向常量字串
p[0]=』x』; //錯誤,常量字串的值不能被改變
cout<
(2)當使用陣列作為函式的引數進行傳遞時,該陣列自動退化為同型別的指標
void printlen(char a[100])
(3)指標引數傳遞記憶體
如果乙個函式的引數是乙個指標,不要使用該指標去申請動態記憶體。例如:
void getmem(char *p, int len)
void test(void)
上面執行錯誤是因為,在函式中重視要為每個引數製作乙個臨時的副本,在getmem中,指標引數p的副本就是_p,在編譯器中會使_p=p。從而在函式體中修改了_p所指向的內容也就修改了p所指向的內容,這也就是指標可以作為輸出引數的根本原因。但是在getmem函式中,臨時的副本_p申請了乙個新的記憶體空間,從而把_p所指向的空間改變了,從此再改變_p所指向的內容時,原來p所指向的內容被沒有變化。而且這裡沒有使用free函式釋放記憶體,從而在每次執行getmem的時候還會洩露一塊記憶體。
解決辦法:通過指向指標的指標 或者 返回指標
(1)指向指標的指標
void getmem1(char **p, int num)
void test1(void)
(2)使用return返回指標
使用函式的返回值來動態傳遞記憶體的這種做法雖然比較好,但是有時候程式設計師常常會把return語句返回的結果弄錯掉。主要是強調不要使用return語句返回指向棧記憶體的指標,因為該內存在函式結束的時候將會被釋放,下次再訪問該記憶體空間時儲存的很可能不是原來的資料。例如:
#include "stdafx.h"
#include
using namespace std;
char *getstr(void)
void test()
void main(void)
注釋:其實這裡可以把下面這個函式中的變數定義做些修改:
char *getstr(void)
這個函式裡的變數定義到靜態儲存區中就可以實現輸出「hello world」
例如 static char str1 = 「hello world」; 或者 char *p = 「hello world」;//這裡需要注意一下第二種方法定義的是一種字元常量
主要參考《高質量c/c++程式設計指南》
motto:the world makes way for
the man who knows where he is going.
C 記憶體管理(一)
1 記憶體分配方式 1 從靜態儲存區域分配。例如使用static 全域性變數。靜態儲存區的資料在程式編譯的時候就已經分配好了,在程式執行期間一直存在,只有在程式推出之後才會釋放。2 在棧上分配。函式內部的區域性變數都是在棧上分配的,在函式階數時儲存空間便被釋放 3 在堆上分配。程式設計師根據自己的需...
C 記憶體管理筆記 一
c 記憶體分配的四個層面 四個層面的比較 記憶體分配與釋放的測試 void p1 malloc 512 512 bytes free p1 complex p2 new complex one object delete p2 void p3 operator new 512 512 bytes o...
C記憶體管理一 概述
我們寫了這麼多年的程式設計師,可能理論方面還比不上大學生。有人 噓 我了,如果有能回答以下幾個問題的同學請舉手 1.面試經常遇到 同學請說說堆疊的區別?2.同學請說說乙個函式在堆疊中呼叫過程 首先要知道函式過程是儲存在什麼中的 3.靜態變數 全域性變數 區域性變數 常量等哪些是儲存在堆中,哪些是棧中...