順序棧實作中,Clear() 函式僅將 top = -1,資料元素仍留在陣列記憶體中,這真的是「清空」嗎?本文從抽象資料型別 (ADT) 契約、記憶體模型、安全性三個層面解析。
順序棧的抽象定義:
base(底部指標)、top(頂部索引)、capacity(容量)。{ base[0], base[1], ..., base[top] }(top >= 0 時)。∅。將 top = -1 即滿足契約:有效元素集合瞬間變空,後續 Push 覆寫舊位置,Pop/Top 回傳錯誤/拋異常。資料結構層面已完成「清空」。
| 層面 | 說明 |
|---|---|
| 物理記憶體 | 陣列 elements[capacity] 仍保留舊位元模式,直到被覆寫或釋放。 |
| 邏輯狀態 | top = -1 宣告「棧內無元素」,所有操作忽略舊資料。 |
| 類比 | 書架書本仍在,但目錄索引歸零;圖書館系統視為「無庫存」。 |
memset(elements, 0, sizeof(T)*capacity) 或 std::fill 覆寫。T 有解構函式(如 std::string, std::vector, 自訂類別),必須逐一呼叫解構函式 釋放內部資源,單純 top=-1 會導致資源洩漏!template <typename T>
class SeqStack {
T* elements;
int top, capacity;
public:
void Clear() {
// 1. 呼叫解構函式(非 POD 必須)
for (int i = 0; i <= top; ++i) {
elements[i].~T(); // 顯式解構
}
// 2. 邏輯清空
top = -1;
// 3. (可選) 安全擦除敏感資料
// std::fill_n(elements, capacity, T{});
}
~SeqStack() {
Clear(); // 復用邏輯
operator delete(elements); // 釋放原始記憶體
}
};
教科書示範 int、char 等 POD 型別時,top = -1 足矣。但進階開發必須處理解構與資源釋放,否則在複雜型別上會產生嚴重 Bug。
top = -1 即滿足 ADT 契約,O(1) 極致效能。理解「邏輯狀態」與「物理存儲」分離,是掌握資料結構實作精髓的關鍵。