krahets/hello-algo · error
雙向佇列為空
Error message
雙向佇列為空
What it means
Unrecoverable Zig @panic from pop(is_front) on the linked-list deque. Guard `if (self.isEmpty()) @panic("雙向佇列為空")` runs before reading `self.front.?.val`, protecting the optional unwrap. Popping an empty deque is treated as a logic error rather than a recoverable empty result.
Source
Thrown at zh-hant/codes/zig/chapter_stack_and_queue/linkedlist_deque.zig:100
node.prev = self.rear;
self.rear = node; // 更新尾節點
}
self.que_size += 1; // 更新佇列長度
}
// 佇列首入列
pub fn pushFirst(self: *Self, num: T) !void {
try self.push(num, true);
}
// 佇列尾入列
pub fn pushLast(self: *Self, num: T) !void {
try self.push(num, false);
}
// 出列操作
pub fn pop(self: *Self, is_front: bool) T {
if (self.isEmpty()) @panic("雙向佇列為空");
var val: T = undefined;
// 佇列首出列操作
if (is_front) {
val = self.front.?.val; // 暫存頭節點值
// 刪除頭節點
var fNext = self.front.?.next;
if (fNext != null) {
fNext.?.prev = null;
self.front.?.next = null;
}
self.front = fNext; // 更新頭節點
// 佇列尾出列操作
} else {
val = self.rear.?.val; // 暫存尾節點值
// 刪除尾節點
var rPrev = self.rear.?.prev;
if (rPrev != null) {
rPrev.?.next = null;View on GitHub (pinned to 69932aed18)
Solutions
- Gate every popFirst()/popLast() with `if (!dq.isEmpty())` or a `dq.size() > 0` check.
- Bound drain loops on size() so they stop exactly when the deque empties.
- Add a wrapper returning ?T if pop-on-empty is a legitimate control-flow signal in your code.
Example fix
// before var v = dq.popFirst(); // after if (dq.isEmpty()) return null; var v = dq.popFirst();
Defensive patterns
Strategy: validation
Validate before calling
// call BEFORE popFirst()/popLast() if (dq.isEmpty()) return null; var v = dq.popFirst();
Prevention
- Gate every pop on isEmpty()/size() before calling.
- Bound drain loops on size() so they stop at exactly zero.
- For sliding-window/monotonic-deque code, assert the deque is non-empty before each pop.
When it happens
Trigger: Call popFirst()/popLast() (both delegate to pop()) on an empty deque, or pop a deque that has been drained to size 0. Any pop issued after the last element was removed will trip it.
Common situations: Drain loops that pop one extra time; sliding-window / monotonic-deque algorithms that pop both ends and overshoot when the window is empty; producer/consumer where the consumer leads the producer.
Related errors
AI-assisted analysis of krahets/hello-algo@69932aed18 (2026-08-13).
Data as JSON: /api/errors/13b90b6f34ee60e3.
Report an issue: GitHub.