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

  1. Bound every index against getSize()/items.len, never against getCapacity().
  2. Use a half-open range `for (0..list.toArray().len)` style iteration so the loop cannot overshoot.
  3. After any mutating op (insert/remove), recompute the index from the new size before re-reading.
  4. 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

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.