動態記憶體分配
程式在執行過程對記憶體進行分配申請與釋放
new運算子
執行時儲存分配,返回可以存放對應型別資料的記憶體地址,指向分配的記憶體空間
- 分配基礎型別記憶體儲存空間
#include <iostream>
using namespace std;
int main() {
string *name;
// 動態在堆空間分配儲存空間,字串值 北門吹雪 值儲存到分配的記憶體空間
name = new string("北門吹雪");
cout << *name << endl;
delete name;
}
- 動態分配一維陣列空間
很多函式使用一維或二維陣列,這些陣列是在編譯時大小未知的,陣列容量的大小隨著函式呼叫動態變大或者變小
#include <iostream>
using namespace std;
void alloc_one_dimensional(int len) {
int *nums;
// 記憶體分配可能會失敗,透過try捕獲程式中的異常
try {
// new對陣列分配記憶體,返回陣列中第一個元素的指標
nums = new int[len];
} catch (bad_alloc& e) {
cout << "記憶體分配失敗" << endl;
}
cout << "動態分配記憶體大小:" << len << endl;
// 是否動態分配的記憶體
delete[] nums;
}
int main() {
alloc_one_dimensional(10);
alloc_one_dimensional(12);
alloc_one_dimensional(13);
}
- 動態分配二維陣列
如果形參是一個二維陣列,必須指定第一維度的大小,
a[][10]
合法,但是a[][]
非法,編譯時就確定陣列的長度,但很多場景下需要每個長度不一的二維陣列
- 因為使用new對陣列進行動態分配,返回陣列中第一個元素的地址,所有建立二維陣列則第二維度只保留指標
#include <iostream>
using namespace std;
template<class T>
void alloc_two_dimensional(T _, int number_of_rows, int number_of_columns) {
// 先動態建立儲存陣列元素的指標
int **matrix = new T *[number_of_rows];
// 然後再依次建立一維陣列
for (int row = 0; row < number_of_rows; row++) {
matrix[row] = new T[number_of_columns];
}
// 修改二維陣列的值
matrix[1][1] = 10;
matrix[2][2] = 10;
matrix[3][3] = 10;
matrix[4][4] = 10;
// 遍歷二維陣列
for (int i = 0; i < number_of_rows; i++) {
for (int j = 0; j < number_of_columns; j++) {
cout << matrix[i][j] << "\t";
}
cout << endl;
}
// 釋放記憶體
// 首先釋放儲存在陣列中的每一個元素指向的陣列
for (int i=0; i < number_of_rows; i++) {
delete[] matrix[i];
}
// 釋放最外層的陣列
delete[] matrix;
}
int main() {
int a;
alloc_two_dimensional(a, 9, 12);
}
delete 運算子
釋放由new運算子動態分配的記憶體空間,呼叫物件關聯型別的解構函式
- 只能操作指標型別物件
- 單個物件使用delete運算子,但多個物件的陣列則需要使用delete[]運算子
#include <iostream>
int main() {
int* y = new int(10);
// 釋放指標指向的單個物件的記憶體,呼叫物件的解構函式
delete y;
int *a = new int[10]{1, 2, 3, 4};
// 釋放指標指向的陣列物件所有記憶體,遍歷依次呼叫陣列中元素對應的解構函式
delete[] a;
}
使用場景:動態分配的記憶體空間(儲存空間)不在需要時