{"record":{"id":"1c441ab0c1756aa4","repo":"krahets/hello-algo","slug":"error-1c441a","errorCode":null,"errorMessage":"栈为空","messagePattern":"栈为空","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"codes/typescript/chapter_stack_and_queue/linkedlist_stack.ts","lineNumber":39,"sourceCode":"    }\n\n    /* 判断栈是否为空 */\n    isEmpty(): boolean {\n        return this.size === 0;\n    }\n\n    /* 入栈 */\n    push(num: number): void {\n        const node = new ListNode(num);\n        node.next = this.stackPeek;\n        this.stackPeek = node;\n        this.stkSize++;\n    }\n\n    /* 出栈 */\n    pop(): number {\n        const num = this.peek();\n        if (!this.stackPeek) throw new Error('栈为空');\n        this.stackPeek = this.stackPeek.next;\n        this.stkSize--;\n        return num;\n    }\n\n    /* 访问栈顶元素 */\n    peek(): number {\n        if (!this.stackPeek) throw new Error('栈为空');\n        return this.stackPeek.val;\n    }\n\n    /* 将链表转化为 Array 并返回 */\n    toArray(): number[] {\n        let node = this.stackPeek;\n        const res = new Array<number>(this.size);\n        for (let i = res.length - 1; i >= 0; i--) {\n            res[i] = node!.val;\n            node = node!.next;","sourceCodeStart":21,"sourceCodeEnd":57,"githubUrl":"https://github.com/krahets/hello-algo/blob/69932aed1891a7b7f6a0de88cd116d3fe13e7032/codes/typescript/chapter_stack_and_queue/linkedlist_stack.ts#L21-L57","documentation":"Thrown by LinkedListStack.pop() ('栈为空') when stackPeek (the head node) is null. pop() first calls peek() (which also throws when stackPeek is null), then re-checks !this.stackPeek and throws a second time. Both guards protect against dereferencing a null head.","triggerScenarios":"Calling pop() on an empty stack; an unbalanced push/pop sequence; a backtracking algorithm that pops one frame too many.","commonSituations":"Expression/AST evaluators using an explicit stack; DFS with an explicit stack that over-pops; calling pop right after construction.","solutions":["Guard with isEmpty()/size before pop: if (!stack.isEmpty()) stack.pop().","Use while (!stack.isEmpty()) for draining.","Audit sentinel handling so pops never exceed pushes."],"exampleFix":"// before\nconst v = stack.pop(); // throws when empty\n// after\nif (!stack.isEmpty()) {\n    const v = stack.pop();\n}","handlingStrategy":"validation","validationCode":"function safePop(stack) {\n  return stack.isEmpty() ? undefined : stack.pop();\n}","typeGuard":"null","tryCatchPattern":"null","preventionTips":["Guard pop with isEmpty()/size.","Ensure push/pop balance in backtracking algorithms.","Use while (!stack.isEmpty()) for draining."],"tags":["typescript","stack","linked-list","empty-state","validation"],"backgroundTag":null,"analyzedSha":"69932aed1891a7b7f6a0de88cd116d3fe13e7032","analyzedAt":"2026-08-13T23:02:37.581Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}