How to use C string returned by C function and free?

This is the C definition:

// must be freed after use
extern const char *string_at(const typ_t *arr, int idx);

The Zig imports:

pub extern fn string_at(arr: ?*const typ_t, idx: c_int) [*c]u8;

How can I use it as string in zig and free it when deinit?

I found that I can use std.mem.span(s) to convert to zig string. But I’m not sure if this can leak memory.

I’m not sure what’s the problem, can’t you just call free() to deinitialize it?

If it’s getting allocated through malloc, you may try using the c_allocators free in the heap section of the standard library:

/// Supports the full Allocator interface, including alignment, and exploiting
/// `malloc_usable_size` if available. For an allocator that directly calls
/// `malloc`/`free`, see `raw_c_allocator`.
pub const c_allocator = Allocator{
    .ptr = undefined,
    .vtable = &c_allocator_vtable,
const c_allocator_vtable = Allocator.VTable{
    .alloc = CAllocator.alloc,
    .resize = CAllocator.resize,
    .free =,

/// Asserts allocations are within `@alignOf(std.c.max_align_t)` and directly calls
/// `malloc`/`free`. Does not attempt to utilize `malloc_usable_size`.
/// This allocator is safe to use as the backing allocator with
/// `ArenaAllocator` for example and is more optimal in such a case
/// than `c_allocator`.
pub const raw_c_allocator = Allocator{
    .ptr = undefined,
    .vtable = &raw_c_allocator_vtable,
const raw_c_allocator_vtable = Allocator.VTable{
    .alloc = rawCAlloc,
    .resize = rawCResize,
    .free = rawCFree,

According to free -, the C version of free from stdlib.h works for:

  • malloc
  • calloc
  • aligned_alloc
  • realloc

That’s what I’d try first. It would be helpful if you posted the body of the C function that you’re referring to.

Thank you! Use the associated free function works :smiley:

1 Like