Comptime string doesn't contain the right characters

A main function calls another function which returns the value of the environment variable LOGNAME .

Printing the value shows �


The program looks like:

const std = @import("std");

pub fn getAccountName(alloc: std.mem.Allocator) ![]const u8 {
    const user = std.process.getEnvVarOwned(alloc, "LOGNAME") catch |err| switch (err) {
        error.EnvironmentVariableNotFound => "~",
        else => return err,
    };

    const username = try std.fmt.allocPrint(alloc, "{s}", .{user});
    defer alloc.free(username);

    return username;
}

pub fn main() void {
    var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
    defer arena.deinit();

    const allocator = arena.allocator();

    const accountName = getAccountName(allocator) catch |err| {
        std.debug.print("Error: {any}\n", .{err});
        return;
    };

    std.debug.print("Hello, {s}!\n", .{accountName});
}

and prints

Hello, �������!

instead of the value of $LOGNAME. I think it may be something to do with allocation but can’t figure it out.

Think about what’s happening here.

5 Likes

Removing defer alloc.free(username); works as expected.

With defer alloc.free(username); garbage value of the same length is being returned (not sure though)

That may help Zig Bits 0x1: Returning slices from functions - Orhun's Blog

2 Likes

Indeed !
Also saw a bunch of numbers trying to fix it before posting.

Thanks for sharing !

Two questions for you to consider:

  • What is the point of calling free? What happens if you don’t call free?
  • What happens if you try to use memory that has been freed?

Some links to help you answer those questions:

Some links that hint at why you’re getting ������� as the output (in Debug mode):

7 Likes