krahets/hello-algo · error

堆疊為空

Error message

堆疊為空

What it means

Unrecoverable Zig @panic from peek() on the array-backed stack. Guard `if (self.isEmpty()) @panic("堆疊為空")` runs before `return self.stack.?.items[self.size() - 1]`; without it, self.size()-1 would underflow (usize wrap) on an empty stack. The stack defines peeking an empty top as a caller logic error.

Source

Thrown at zh-hant/codes/zig/chapter_stack_and_queue/array_stack.zig:40

        // 析構方法(釋放記憶體)
        pub fn deinit(self: *Self) void {
            if (self.stack == null) return;
            self.stack.?.deinit();
        }

        // 獲取堆疊的長度
        pub fn size(self: *Self) usize {
            return self.stack.?.items.len;
        }

        // 判斷堆疊是否為空
        pub fn isEmpty(self: *Self) bool {
            return self.size() == 0;
        }

        // 訪問堆疊頂元素
        pub fn peek(self: *Self) T {
            if (self.isEmpty()) @panic("堆疊為空");
            return self.stack.?.items[self.size() - 1];
        }  

        // 入堆疊
        pub fn push(self: *Self, num: T) !void {
            try self.stack.?.append(num);
        } 

        // 出堆疊
        pub fn pop(self: *Self) T {
            var num = self.stack.?.pop();
            return num;
        } 

        // 返回 ArrayList
        pub fn toList(self: *Self) std.ArrayList(T) {
            return self.stack.?;
        }

View on GitHub (pinned to 69932aed18)

Solutions

  1. Prepend `if (!stk.isEmpty())` before every peek().
  2. Drive the algorithm so peek() only runs in a branch that already established size() > 0.
  3. Provide a safe wrapper returning ?T for empty-top cases.

Example fix

// before
const top = stk.peek();
// after
const top = if (stk.isEmpty()) null else stk.peek();
Defensive patterns

Strategy: validation

Validate before calling

// call BEFORE peek()
if (stk.isEmpty()) return null;
const top = stk.peek();

Prevention

When it happens

Trigger: Call peek() on an ArrayStack with zero elements: never pushed, or fully popped. The guard is essential here because the alternative is a usize underflow on `size - 1`, which would be a silent memory-safety violation.

Common situations: Expression evaluators that peek for a pending operator before the first push; parsers that peek the symbol stack after it empties; tests that assert on the top of a newly constructed stack; backtracking that peeks the work stack after draining it.

Related errors


AI-assisted analysis of krahets/hello-algo@69932aed18 (2026-08-13). Data as JSON: /api/errors/330e1fb4d44c6e2c. Report an issue: GitHub.