Reputation: 730
Please bear with this question as it might sound very dumb but this is my first experience with manual memory management.
const std = @import("std");
const Allocator = std.mem.Allocator;
pub fn main() !void {
for (0..2) |_| {
var buff = [10]u8{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
std.debug.print("{*}\n", .{&buff});
}
}
When I run the above code, I get this output
[10]u8@16ba971e8
[10]u8@16ba971e8
Does Zig allocate the buffer at the same address ? This means any data stored in that array will get overwritten in the 2nd iteration.
Upvotes: 0
Views: 185
Reputation: 3575
Stack-allocated data is gone when its scope exits, so in this for loop, the array is put on the stack, its address is printed, and then its scope exits and using it again would be a use-after-free bug.
This is how the stack works - there's no way to allocate data to the stack that will stick around longer than the scope it was made in.
If you need pointers to stick around after their scope exits, they need to be heap-allocated.
const std = @import("std");
pub fn main() !void {
var gpa_alloc = std.heap.GeneralPurposeAllocator(.{}){};
defer std.debug.assert(gpa_alloc.deinit() == .ok);
const gpa = gpa_alloc.allocator();
for (0..2) |_| {
const buff = try gpa.alloc(u8, 10);
for(buff, 0..) |*item, i| item.* = @intCast(i + 1);
std.debug.print("{*}\n", .{buff});
}
}
In this example, the memory is never freed, so the code will error on exit, but two different addresses will be printed.
Upvotes: 2