I'm working on Advent of Code with Zig and I'm at day 3. I've uploaded the code I wrote. The puzzle description and the code is here: https://github.com/secondspass/adventofcodeday3 . The code is in day3_part2.zig, the input file is day3.in. I run with zig run day3_part2.zig
.
I get one of two outputs when I run the code. Either the below integer overflow in the co2ScrubberRating
function.
thread 174927 panic: integer overflow
/home/subil/Projects/zig_learn/adventofcode/test/day3_part2.zig:80:25: 0x23401c in co2ScrubberRating (day3_part2)
while (i >= 0) : (i -= 1) {
^
/home/subil/Projects/zig_learn/adventofcode/test/day3_part2.zig:112:42: 0x22c80e in main (day3_part2)
var co2rating = try co2ScrubberRating(numbers.items[0..], allocator);
^
/home/subil/tools/zig-0.9.0/lib/std/start.zig:535:37: 0x224eaa in std.start.callMain (day3_part2)
const result = root.main() catch |err| {
^
/home/subil/tools/zig-0.9.0/lib/std/start.zig:477:12: 0x208ace in std.start.callMainWithArgs (day3_part2)
return @call(.{ .modifier = .always_inline }, callMain, .{});
^
/home/subil/tools/zig-0.9.0/lib/std/start.zig:391:17: 0x207b56 in std.start.posixCallMainAndExit (day3_part2)
std.os.exit(@call(.{ .modifier = .always_inline }, callMainWithArgs, .{ argc, argv, envp }));
^
/home/subil/tools/zig-0.9.0/lib/std/start.zig:304:5: 0x207962 in std.start._start (day3_part2)
@call(.{ .modifier = .never_inline }, posixCallMainAndExit, .{});
^
Aborted (core dumped)
or I would get the following output, where the binary number on the second line is the output of the co2ScrubberRating
function is a seemingly random number.
100111011110
1000000111101101010111
And which output I get is random every time I run the zig run day3_part2.zig
.
I'm passing the same ArrayList.items slice and allocator to both the oxygenGeneratorRating
and the co2ScrubberRating
. And if I only run one of those functions in the main (i.e. I comment out one of them), the correct output is produced for that function. But if I have both functions in the main, I get the random bad outputs from the co2ScrubberRating
function. And I have no idea why it behaves like that. I guess it has something to do with the ArrayList being passed to a function a second time.
Any insight would be appreciated.
This is because readToNumberList
is returning a pointer to stack memory that goes out of scope, which is undefined behaviour and not yet caught in debug builds.
fn readNumberList(…) !*std.ArrayList(u32) {
…
return &numbers;
Changing the code to
fn readNumberList(…) !std.ArrayList(u32) {
…
return numbers;
fixes the issue.
You could also fix it by putting the ArrayList struct in heap memory:
fn readNumberList(…) !*std.ArrayList(u32) {
const numbers = try allocator.create(std.ArrayList(u32));
numbers.* = std.ArrayList(u32).init(allocator);
…
return numbers;