陣列是最常用的一種資料結構,其缺點是使用時必須確定陣列大小,因此會帶來一些不便:
1)需要儲存的資料大小不確定時,預先開闢的空間太小裝不下,太大則浪費空間;
2)使用的資料大部分預設儲存在棧(stack)裡,由系統管理,自動分配,自動刪除。但是stack很小,如果讀取的資料很大的話容易溢位。
3)系統要等到變數週期結束時才會釋放記憶體,當記憶體比較緊缺時,沒法立即釋放。
4)動態分配的優點:根據函式呼叫的需要,動態地分配和釋放儲存空間,大大提高了記憶體的使用效率。
1)c語言使用標準庫函式malloc()和free()來實現動態分配。
2)void *malloc(int size):申請size個位元組空間,返回值是void *(未確定型別的指標,即在申請記憶體時使用者還不知道要用來儲存什麼型別的資料,
c/c++
規定void *
型別可以強制轉換為任意型別),所以需要做強制型別轉換為int*指標。
3)malloc的引數是記憶體大小,以位元組為單位,表示要申請多少個位元組。而在不同的系統裡面int型別占用的位元組不一樣,而且malloc所以首先需要使用
sizeof
計算。
4)malloc只能分配記憶體,不能對所得的記憶體進行初始化,所以其初值為隨機的。
5)注意事項:申請記憶體空間後必須檢查是否分配成功,用完釋放,使原來指向該記憶體的指標指向
null,防止後面程式不小心使用了它。
6)c程式只能用malloc/free管理動態記憶體;
1)c++裡的類class裡面的建構函式是在類的例項化時自動呼叫,而不能手動呼叫,如果像c語言一樣使用malloc來為class動態分配記憶體,那麼將無法呼叫建構函式。
2)c++使用運算子new和delete來完成記憶體動態分配,使用new時自動呼叫建構函式,使用完畢用delete釋放記憶體時會自動呼叫析構函式。
3)使用new動態建立物件時,只需指定其資料型別,不必為該物件命名,例:
a)int *pi = new int;// pi 指向乙個沒有初始化的int
b)int *pi=new int( );//初始化為0
c)string *ps=new string( );//初始化為空字串(對於提供了預設建構函式的類型別,沒有必要對其物件進行值初始化)
d)int *pi=new int(100);//指標pi所指向的物件初始化為100
e)string *ps=new string(10,'9');//*ps 為「9999999999」
4)new返回指定型別的指標,並且可以自動計算所需大小,例如:
a)int *p; p = new int;//返回型別為int* 型別(整數型指標),分配大小為 sizeof(int);
b)int* parr; parr = new int [100];//返回型別為 int* 型別(整數型指標),分配大小為 sizeof(int) * 100;
c)int* p; p = (int *) malloc (sizeof(int)*128);//分配128個(可根據實際需要替換該數值)整型儲存單元,並將這128個連續的整型儲存單元的首位址儲存到指標變數p中。
d)double *pd=(double *) malloc (sizeof(double)*12);//分配12個double型儲存單元,並將首位址儲存到指標變數pd中。
5)使用delete釋放動態建立的物件,例:
a)delete pi ;// 釋放單個物件,此時pi指標變成了懸垂指標(懸垂指標指向曾經存放物件的記憶體,但該物件已經不存在了)
b)delete [ ]pi;//釋放陣列
#includeusing namespace std;
void main()
//step3:使用陣列
for (int i = 0; i < len; i++)
//step4: 釋放記憶體
free(arr);
}
2) new-delete
#includeusing namespace std;
void main()
//step3:使用陣列
cout << "your array is: " << endl;
for (int i = 0; i < len; i++)
//step4: 釋放記憶體
delete arr;
}
#includeusing namespace std;
void main()
//step2: 輸入資料
for (int i = 0; i < row; i++)
//step3:使用陣列
cout << "your array is: " << endl;
for (int i = 0; i < row; i++)
cout << endl;
} //step4: 釋放記憶體
for (int i = 0; i < row; i++)
}
2)new-delete
#includeusing namespace std;
void main()
//step2: 輸入資料
for (int i = 0; i < row; i++)
//step3:使用陣列
cout << "your array is: " << endl;
for (int i = 0; i < row; i++)
cout << endl;
} //step4: 釋放記憶體
delete arr;
}
3)vector
#include#includeusing namespace std;
void main()
//step3:使用陣列
cout << "your array is: " << endl;
for (int i = 0; i < row; i++)
cout << endl;
} //step4: 無需釋放
}
1)記憶體洩漏(memory leak)是指程式中己動態分配的堆記憶體由於某種原因程式未釋放或無法釋放,造成系統記憶體的浪費,導致程式執行速度減慢甚至系統崩潰等嚴重後果。
2)記憶體洩漏具有隱蔽性和累積性,不易被發現。
3)在c或c++程式執行時的變數主要有三種分配方式:堆分配、棧分配、全域性和靜態分配,記憶體洩漏主要發生在堆分配中,即「配置了記憶體後,所有指向該記憶體的指標都遺失了」。
4)當開發程式中使用動態儲存變數較多和頻繁使用函式呼叫時,容易發生記憶體管理錯誤,常見的有:
a) 分配乙個記憶體塊並使用其中未經初始化的內容;
b) 釋放乙個記憶體塊,但繼續引用其中的內容;
c) 子函式中分配的記憶體空間在主函式出現異常中斷時、或主函式對子函式返回的資訊使用結束時,沒有對分配的記憶體進行釋放;
d) 程式實現過程中分配的臨時內存在程式結束時,沒有釋放臨時記憶體。
5)在記憶體中供使用者使用的記憶體空間分為三部分:
a)程式儲存區:
b)靜態儲存區:該區資料在程式的開始就分配好記憶體區,在整個程式執行過程中它們所佔的儲存單元是固定的,在程式結束時就釋放,因此靜態儲存區資料一般為全域性變數。
c)動態儲存區:該區資料在程式執行過程中根據需要動態分配和動態釋放的儲存單元,動態儲存區資料有三類函式形參變數、區域性變數和函式呼叫時的現場保護與返回位址。
C C 動態分配
分配失敗,返回空指標 c 兩個函式malloc 與free 下面是 malloc 函式的宣告。void malloc size t size 返回的是void 無型別 指標,故需要對指標做轉換 size 分配的位元組數 include include include malloc 函式需要的標頭檔案...
記憶體動態分配
陣列的元素儲存於記憶體中連續的位置上。當乙個陣列被宣告時,它所需要的內存在編譯時就被分配。但是,你也可以使用動態記憶體分配在執行時為它分配記憶體。malloc所分配的是一塊連續的記憶體。例如,如果請求它分配100個位元組的記憶體,那麼它實際分配的記憶體就是100個連續的位元組,並不會分開位於兩塊或多...
動態分配記憶體
動態記憶體分配即分配記憶體大小在執行時才確定,一般在堆中分配。c語言動態記憶體分配相關的函式。include void malloc size t size malloc的使用比較直接,乙個成功的malloc呼叫返回分配的size大小的記憶體的指標。失敗時返回null並將錯誤 置為enomem。教材...