{"record":{"id":"61ac7c074f7815f8","repo":"krahets/hello-algo","slug":"error-61ac7c","errorCode":null,"errorMessage":"索引越界","messagePattern":"索引越界","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"zh-hant/codes/zig/chapter_array_and_linkedlist/my_list.zig","lineNumber":58,"sourceCode":"        const new_item_ptr = &self.items[self.items.len - 1];\n        new_item_ptr.* = item;\n    }\n\n    // 獲取串列長度（當前元素數量）\n    pub fn getSize(self: *Self) usize {\n        return self.items.len;\n    }\n\n    // 獲取串列容量\n    pub fn getCapacity(self: *Self) usize {\n        return self.capacity;\n    }\n\n    // 訪問元素\n    pub fn get(self: *Self, index: usize) i32 {\n        // 索引如果越界，則丟擲異常，下同\n        if (index < 0 or index >= self.items.len) {\n            @panic(\"索引越界\");\n        }\n        return self.items[index];\n    }\n\n    // 更新元素\n    pub fn set(self: *Self, index: usize, num: i32) void {\n        // 索引如果越界，則丟擲異常，下同\n        if (index < 0 or index >= self.items.len) {\n            @panic(\"索引越界\");\n        }\n        self.items[index] = num;\n    }\n\n    // 在中間插入元素\n    pub fn insert(self: *Self, index: usize, item: i32) !void {\n        if (index < 0 or index >= self.items.len) {\n            @panic(\"索引越界\");\n        }","sourceCodeStart":40,"sourceCodeEnd":76,"githubUrl":"https://github.com/krahets/hello-algo/blob/69932aed1891a7b7f6a0de88cd116d3fe13e7032/zh-hant/codes/zig/chapter_array_and_linkedlist/my_list.zig#L40-L76","documentation":"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.","triggerScenarios":"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`.","commonSituations":"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.","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."],"exampleFix":"// before\nconst v = list.get(i);          // panics when i >= len\n// after\nif (i >= list.size()) return;\nconst v = list.get(i);","handlingStrategy":"validation","validationCode":"// call BEFORE get(index)\nif (index >= list.size()) return;  // index is usize, never < 0\nconst v = list.get(index);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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."],"tags":["zig","array-list","index-out-of-bounds","data-structure","unsigned-trap"],"backgroundTag":null,"analyzedSha":"69932aed1891a7b7f6a0de88cd116d3fe13e7032","analyzedAt":"2026-08-13T23:02:37.581Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}