Static array of bytes misbehave when increasing number of elements

Hi,

I have a really odd behavior using a u8 array.

var buffer = [_]u8 { 1, 0, 0, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0x42, 0xc8, 0x3e};

Initializes a constant buffer with the values as specified,

If I however increase the array size by one using an additional element,

var buffer = [_]u8 { 1, 0, 0, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0x42, 0xc8, 0x3e, 0xfa, };

initializes the array with “garbage data”. As a Zig newcomer, with reasonable low-level development experience in various other technologies, I find this behavior very interesting and troubling.

This is done on:

  1. A Linux 64-bit machine with the Zig 0.13.0
  2. The above code is done in a test.
  3. I will do additional tests, to see what happens to the buffer pointer, relative to other pointers etc… And see if it behaves different in an application.

Regards

Without seeing more of the code it’s hard to figure out what’s going on.
I’d guess that it’s probably a variant of returning a pointer to an array on the stack.
In Zig you have to manually allocate memory if you want to return a slice from a function.

1 Like

Dear IntegratedQuantum,

Thanks for responding.

There is really nothing more to it. That line misbehaves even if I put it in a two line program…

Assessing your comment, I can see that the buffer, with 15 bytes is allocated on the stack - or it should be. That is exactly what I am aiming for… and has it working until the moment that I initialize it to 16 bytes…

I will provide a memory view shortly… But something is not right - and it likely is me - just cannot see how/why.

pub fn main() !void {
    var a : u8 = 10;
    var buffer =[_] u8 { 1, 0, 0, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0x42, 0xc8, 0x3e };
    var b : u8 = 10;

    std.debug.print("{s}\n", .{&a});
    std.debug.print("{s}\n", .{&buffer[0]});
    std.debug.print("{s}\n", .{&b});
    // _= Reader.new(&buffer, buffer.len);
}
u8@7fffffffddc7
u8@7fffffffddc8
u8@7fffffffddd7

Correct… See how nice and tight the stack is.

I have changed absolutely nothing… now it works… ! It still fails in the test, with the exact same line of code. I have this problem in main again… so my guess is that it is related to the build… which is even more worrying… for then I am missing some much bigger foundational issue.

It will be easier for others to help you if you post a complete, compilable program that demonstrates the problem. If you’re currently running into this problem in your main function, then post the full code of that main function.

2 Likes

@castholm - the code really is that simple. After ditching my IDE/editor of choice I jumped to the command line. And now both the tests and the “main” works consistently. It is the Editor debugger that is writing rubbish into the stack, with the red herring and trigger being the array size from 15 to 16.

Apologies - I was stumped - but I have the answer. ZigBrains with GDB debugging creates this issue. It somehow corrupts the stack on debugging.
Using ZigBrains with LLDB fixes the issue.

Post your code.

This works fine:

const std = @import("std");

pub fn main() !void {
    const buffer = [_]u8{ 1, 0, 0, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0x42, 0xc8, 0x3e, 0xfa };
    std.debug.dumpHex(&buffer);
}
$ zig run buffer.zig
0000000001000730  01 00 00 01 03 00 00 00  00 00 00 00 42 C8 3E FA  ............B.>.

Hi @squeek502, yes - I confirmed the problem was in using GDB with ZigBrains that, in debugging trashes the stack; EXACLTY when I go from 15 bytes array to 16 bytes. Switching to LLDB fixes the issue. So it was a tooling issue that misdirected me.
Thanks for everybody that responded. Even though it is not a language, source or understanding issue from my side, it is still a valid issue - just not a Zig issue.

I hope that this thread/solution help somebody else.

2 Likes