靜態陣列 int a[10][10] 編譯期確定大小與位置;動態陣列需執行期根據實際需求配置記憶體,支援大小變化。典型場景:工廠資料庫儲存不定人數各車間工人姓名。
關鍵技術:malloc/realloc 管理原始記憶體 + placement new 呼叫建構函式 + 手動呼叫解構函式。
template<typename T>
class Dynamic1Dim {
T* m_pBuf;
int m_iSize;
public:
Dynamic1Dim() : m_iSize(1) {
m_pBuf = (T*)malloc(sizeof(T));
new(m_pBuf) T(); // placement new 建構第一個元素
}
T& operator[](int index) {
if (index < 0) throw std::out_of_range("negative index");
if (index >= m_iSize) EnlargeDim(index + 1);
return m_pBuf[index];
}
bool EnlargeDim(int newSize) {
m_pBuf = (T*)realloc(m_pBuf, sizeof(T) * newSize);
for (int i = m_iSize; i < newSize; ++i)
new(&m_pBuf[i]) T(); // 新增空間建構物件
m_iSize = newSize;
return true;
}
~Dynamic1Dim() {
for (int i = 0; i < m_iSize; ++i) m_pBuf[i].~T(); // 關鍵:手動解構
free(m_pBuf);
}
};
template<typename T>
class Dynamic2Dim {
Dynamic1Dim<T>* m_pYBuf;
int m_iYSize;
public:
Dynamic2Dim() : m_iYSize(1) {
m_pYBuf = (Dynamic1Dim<T>*)malloc(sizeof(Dynamic1Dim<T>));
new(m_pYBuf) Dynamic1Dim<T>();
}
Dynamic1Dim<T>& operator[](int y) {
if (y < 0) throw std::out_of_range("negative index");
if (y >= m_iYSize) EnlargeY(y + 1);
return m_pYBuf[y];
}
bool EnlargeY(int newSize) {
m_pYBuf = (Dynamic1Dim<T>*)realloc(m_pYBuf, sizeof(Dynamic1Dim<T>) * newSize);
for (int i = m_iYSize; i < newSize; ++i)
new(&m_pYBuf[i]) Dynamic1Dim<T>();
m_iYSize = newSize;
return true;
}
~Dynamic2Dim() {
for (int i = 0; i < m_iYSize; ++i) m_pYBuf[i].~Dynamic1Dim();
free(m_pYBuf);
}
};
Dynamic2Dim<int> m_dim; // 1x1
m_dim[1][3] = 33; // 自動擴展為 2x4(第0、2、3行維持1元素)
m_dim[4][10] = 710; // 自動擴展為 5x11(第4行11元素,其他行不變)
arr[6][6] 讀取時不應自動擴容。解法:引入 Proxy 類別區分 operator[] const/non-const 版本,const 版本超出範圍拋出異常。realloc 頻率與記憶體複製開銷。realloc 複製開銷大,可改用 malloc 新配置 + 手動複製 + free 舊區塊。Dynamic1Dim<T>& 而非 T*,無法直接指標運算:T* p = dim[3]; // 編譯錯誤。此實作提供類似靜態陣列 arr[i][j] 的直觀語法,內部自動處理記憶體管理與擴容,適合大小不可預知的二維資料儲存。生產環境建議加入上述優化與邊界檢查。