ash / advent-2019

5 stars 2 forks source link

Dangling pointer in Zig function example #2

Closed SyrupThinker closed 4 years ago

SyrupThinker commented 4 years ago

https://github.com/ash/advent-2019/blob/c6e6b91a571651e71b412f1afd20e05a435050bf/Zig/function.zig#L5

This buffer is allocated on the stack, retuning a pointer (in form of a slice) to it is incorrect.

The way this code fails can be seen in the following example:

// Tested using zig 0.5.0+4d54e9a4f
// Can be adapted for the 0.5.0 release
const warn = @import("std").debug.warn;
const fmt = @import("std").fmt;

fn greet(name: []const u8) ![]const u8 {
    var buf: [100]u8 = undefined;

    return fmt.bufPrint(buf[0..], "Hello, {}!", .{name});
}

pub fn main() void {
    const a = greet("Dangling");
    warn("{}\n", .{a});
    const b = greet("Pointer");
    warn("{}\n", .{b});
    warn("{}\n", .{a});
}
$ zig run dangling.zig
Hello, Dangling!
Hello, Pointer!
Hello, Pointer!�

This problem can be solved by heap allocating the memory as mentioned in the blog post.

ash commented 4 years ago

I believe making it global also solves it.

SyrupThinker commented 4 years ago

The example will still fail in the way I describe, its just not stack data being printed, but that of the last greet call.

You could argue that thats intented behavior, but as an example for learning the language its in my opinion misleading.