int *arr1D = new int[m]; // 分配
delete[] arr1D; // 釋放(必須用 [])
// 分配
int **arr2D = new int*[m];
for (int i = 0; i < m; i++)
arr2D[i] = new int[n];
// 釋放(逆序)
for (int i = 0; i < m; i++)
delete[] arr2D[i];
delete[] arr2D;
優點:每行長度可不同(鋸齒數組)。
缺點:內存不連續,訪問需兩次間接寻址,缓存不友好。
// 分配
int **arr2D = new int*[m];
arr2D[0] = new int[m * n]; // 一塊連續內存
for (int i = 1; i < m; i++)
arr2D[i] = arr2D[i-1] + n; // 指針算術定位行首
// 釋放
delete[] arr2D[0]; // 釋放數據塊
delete[] arr2D; // 釋放指針數組
優點:內存連續,單次分配/釋放,緩存友好,訪問 arr2D[i][j] 效率極高。
缺點:所有行長度必須相同。
// 分配
int ***arr3D = new int**[m];
for (int i = 0; i < m; i++) {
arr3D[i] = new int*[n];
for (int j = 0; j < n; j++)
arr3D[i][j] = new int[h];
}
// 釋放(三層循環逆序)
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++)
delete[] arr3D[i][j];
delete[] arr3D[i];
}
delete[] arr3D;
亦可用連續內存版(一維大塊 + 多層指針索引),原理同二維方式 2。
需求:支持 a[i][j] 和 a(i,j) 兩種訪問,支持賦值拷貝、析構釋放。
class Array2 {
int rows, cols;
int **data; // 方式2:連續內存
public:
Array2(int r=0, int c=0): rows(r), cols(c), data(nullptr) {
if (rows && cols) {
data = new int*[rows];
data[0] = new int[rows*cols];
for (int i = 1; i < rows; i++) data[i] = data[i-1] + cols;
}
}
~Array2() {
if (data) { delete[] data[0]; delete[] data; }
}
int* operator[](int i) { return data[i]; } // 支持 a[i][j]
int operator()(int i, int j) const { return data[i][j]; } // 支持 a(i,j)
Array2& operator=(const Array2& other) {
if (this == &other) return *this;
if (data) { delete[] data[0]; delete[] data; }
rows = other.rows; cols = other.cols;
if (rows && cols) {
data = new int*[rows];
data[0] = new int[rows*cols];
for (int i = 1; i < rows; i++) data[i] = data[i-1] + cols;
memcpy(data[0], other.data[0], rows*cols*sizeof(int));
} else data = nullptr;
return *this;
}
};
| 場景 | 推薦方式 | 釋放順序 |
|---|---|---|
| 一維 | new T[n] | delete[] p |
| 二維(高性能) | 連續塊 + 行指針 | delete[] p[0]; delete[] p; |
| 二維(鋸齒) | 分行分配 | 先删各行 delete[] p[i],再删 delete[] p |
| 三維+ | 同理,層層指針 | 從最內層向外逐層 delete[] |
std::vector> :自動管理,但非連續。std::vector + 手動索引 [i*cols + j]:連續、安全、推薦。std::unique_ptr + 自定義刪除器:RAII 管理裸指針。除非極致性能或特殊內存佈局需求,**優先使用標準庫容器**。手動 new/delete 易出錯(異常安全、拷貝語義、內存洩漏)。