首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

C++ 二維/多維數組動態分配與釋放完整指南

     編輯:關於C++

一、一維數組


int *arr1D = new int[m];      // 分配
delete[] arr1D;               // 釋放(必須用 [])

二、二維數組:兩種主流方式

方式 1:指針數組 + 分別分配每行(不連續,靈活)


// 分配
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;

優點:每行長度可不同(鋸齒數組)。
缺點:內存不連續,訪問需兩次間接寻址,缓存不友好。

方式 2:一塊連續內存 + 指針數組指向各行起始(推薦,高性能)


// 分配
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。

四、實戰案例:自定義二維數組類 Array2

需求:支持 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[]

六、現代 C++ 替代方案

  • std::vector>:自動管理,但非連續。
  • std::vector + 手動索引 [i*cols + j]:連續、安全、推薦。
  • std::unique_ptr + 自定義刪除器:RAII 管理裸指針。

除非極致性能或特殊內存佈局需求,**優先使用標準庫容器**。手動 new/delete 易出錯(異常安全、拷貝語義、內存洩漏)。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved