Why Zig arrays consume so much stack memory?

I was experimenting with stack overflow and found out that when I allocate 1MB array I get stack overflow after 3 recursions. But I have 8MB of stack. I tested with C equivalent and with C I get 7 recursions (which is expected I guess).

Here is Zig code compiled with zig build-exe recursive.zig:

const std = @import("std");

fn recursive() void {
    var array: [1024 * 1024]u32 = undefined;
    std.debug.print("array is at: {*}\n", .{&array});
    recursive();
}

pub fn main() !void {
    recursive();
}

and output:

$ ./recursive
array is at: [1048576]u32@be59158c
array is at: [1048576]u32@be191574
array is at: [1048576]u32@bdd9155c
Segmentation fault

Notice that 0xbe59158c - 0xbe191574 = 4194328 (in decimal) which is around 4MB

Here is the C code compiled with gcc -o crecursive crecursive.c:

#include <stdio.h>

void recursive() {
    char array[1024 * 1024];
    printf("array is at 0x%X\n", (unsigned long)&array[0]);
    recursive();
}

int
main(int argc, char **argv) {
    recursive();
}

and output:

$ ./crecursive
array is at 0xBE705560
array is at 0xBE605558
array is at 0xBE505550
array is at 0xBE405548
array is at 0xBE305540
array is at 0xBE205538
array is at 0xBE105530
Segmentation fault

Notice that 0xBE705560 - 0xBE605558 = 1048584 (in decimal) which is a little more than 1MB.

The system is 32bit with default stack size 8MB as indicated by:

 $ ulimit -s
8192

So there is something weird going on. In Zig arrays consume around 4MB judging by addresses but if they consume so much memory why is it possible to allocate 3 of them? Segfault should happen after first recurion because stack has only 8MB of memory.

Your Zig array element is u32 (4 bytes each) but your C array element is char (1 byte each).

10 Likes

Ah, yes ofcourse. Brainfart.

Now I get 15 recursions so I guess Zig overrides ulimit -s somehow?

1 Like

I found this issue that implements stack sizing so this answers why is stack 16MB: increase the stack size on Linux before calling main() to match GNU_STACK program header · Issue #8708 · ziglang/zig · GitHub

1 Like