krahets/hello-algo · error
索引越界
Error message
索引越界
What it means
Unrecoverable Zig @panic from get(index) on the dynamic-array MyList. The guard `if (index < 0 or index >= self.items.len) @panic("索引越界")` rejects out-of-range indices before indexing self.items. Note index is declared usize (unsigned), so the `index < 0` half is dead code — only the `index >= self.items.len` test can ever be true. The list panics because random access past the live element count is a caller contract violation.
Source
Thrown at zh-hant/codes/zig/chapter_array_and_linkedlist/my_list.zig:58
const new_item_ptr = &self.items[self.items.len - 1];
new_item_ptr.* = item;
}
// 獲取串列長度(當前元素數量)
pub fn getSize(self: *Self) usize {
return self.items.len;
}
// 獲取串列容量
pub fn getCapacity(self: *Self) usize {
return self.capacity;
}
// 訪問元素
pub fn get(self: *Self, index: usize) i32 {
// 索引如果越界,則丟擲異常,下同
if (index < 0 or index >= self.items.len) {
@panic("索引越界");
}
return self.items[index];
}
// 更新元素
pub fn set(self: *Self, index: usize, num: i32) void {
// 索引如果越界,則丟擲異常,下同
if (index < 0 or index >= self.items.len) {
@panic("索引越界");
}
self.items[index] = num;
}
// 在中間插入元素
pub fn insert(self: *Self, index: usize, item: i32) !void {
if (index < 0 or index >= self.items.len) {
@panic("索引越界");
}View on GitHub (pinned to 69932aed18)
Solutions
- Bound every index against getSize()/items.len, never against getCapacity().
- Use a half-open range `for (0..list.toArray().len)` style iteration so the loop cannot overshoot.
- After any mutating op (insert/remove), recompute the index from the new size before re-reading.
- Remove the redundant `index < 0` clause since index is usize — it can never fire and obscures the real check.
Example fix
// before const v = list.get(i); // panics when i >= len // after if (i >= list.size()) return; const v = list.get(i);
Defensive patterns
Strategy: validation
Validate before calling
// call BEFORE get(index) if (index >= list.size()) return; // index is usize, never < 0 const v = list.get(index);
Prevention
- Bound indices on getSize()/items.len, never on getCapacity().
- Use half-open ranges (`0..len`) for iteration to avoid off-by-one.
- Drop the dead `index < 0` clause — index is usize and can never be negative.
When it happens
Trigger: Call get(i) with i >= current element count (self.items.len), e.g. reading at the capacity's end before add() has grown the live length, or calling get() right after remove() shrank the list. Negative-style underflow (wrapping a large usize) will also appear as `index >= len`.
Common situations: Off-by-one loops (`i <= size` instead of `i < size`); assuming capacity == size and indexing up to getCapacity(); reusing an index captured before a remove()/clear(); mixing getCapacity() and size() in bounds checks.
Related errors
AI-assisted analysis of krahets/hello-algo@69932aed18 (2026-08-13).
Data as JSON: /api/errors/61ac7c074f7815f8.
Report an issue: GitHub.