krahets/hello-algo · error · Error
堆疊為空
Error message
堆疊為空
What it means
An Error '堆疊為空' ('stack is empty') thrown by pop() in LinkedListStack (linkedlist_stack.ts:39). pop() first calls peek() (which is guarded), then advances stackPeek to stackPeek.next; the `if (!this.stackPeek)` check blocks unlinking the head of an empty list, preventing a null dereference when reading .next on null.
Source
Thrown at zh-hant/codes/typescript/chapter_stack_and_queue/linkedlist_stack.ts:39
}
/* 判斷堆疊是否為空 */
isEmpty(): boolean {
return this.size === 0;
}
/* 入堆疊 */
push(num: number): void {
const node = new ListNode(num);
node.next = this.stackPeek;
this.stackPeek = node;
this.stkSize++;
}
/* 出堆疊 */
pop(): number {
const num = this.peek();
if (!this.stackPeek) throw new Error('堆疊為空');
this.stackPeek = this.stackPeek.next;
this.stkSize--;
return num;
}
/* 訪問堆疊頂元素 */
peek(): number {
if (!this.stackPeek) throw new Error('堆疊為空');
return this.stackPeek.val;
}
/* 將鏈結串列轉化為 Array 並返回 */
toArray(): number[] {
let node = this.stackPeek;
const res = new Array<number>(this.size);
for (let i = res.length - 1; i >= 0; i--) {
res[i] = node!.val;
node = node!.next;View on GitHub (pinned to 69932aed18)
Solutions
- Check stack.isEmpty() (or stkSize === 0) before pop.
- Drain with `while (!stack.isEmpty())`.
- Track pushes and never pop more than that.
- Return an optional from a wrapper when empty is a normal outcome.
Example fix
// before: popping an empty linked-list stack throws
const top = stack.pop();
// after: guard first
if (!stack.isEmpty()) {
const top = stack.pop();
} Defensive patterns
Strategy: validation
Validate before calling
// Guard LinkedListStack pop
function safePop(stack: LinkedListStack): number | undefined {
return stack.isEmpty() ? undefined : stack.pop();
}
while (!stack.isEmpty()) {
const top = stack.pop();
} Type guard
const nonEmpty = (stack: LinkedListStack): boolean => !stack.isEmpty();
Try / catch
try {
const top = stack.pop();
} catch (e) {
if (e instanceof Error && e.message === '堆疊為空') {
// stack empty; handle gracefully
} else throw e;
} Prevention
- Check isEmpty() before pop.
- Track pushes and never pop more than that.
- Drain with `while (!stack.isEmpty())`.
- Reset shared stack instances between runs.
When it happens
Trigger: Calling stack.pop() when this.stackPeek is null (stkSize === 0). Popping more than you pushed, or popping a freshly constructed `new LinkedListStack()`.
Common situations: Unbalanced push/pop in expression evaluation or backtracking; popping after a previous pop emptied the stack; DFS that pops on backtrack without checking depth; reusing a stack instance across runs without resetting state.
Related errors
AI-assisted analysis of krahets/hello-algo@69932aed18 (2026-08-13).
Data as JSON: /api/errors/5295481e0dbefec8.
Report an issue: GitHub.