# Trouble concatenating strings using an allocator

**URL:** <https://ziggit.dev/t/trouble-concatenating-strings-using-an-allocator/13632>\
**Category:** Help\
**Tags:** language, standard-library, string\
**Created:** [December 24, 2025, 1:39am UTC](https://ziggit.dev/t/trouble-concatenating-strings-using-an-allocator/13632 "2025-12-24T01:39:58Z")\
**Posts on this page:** 17\
**Page:** 1

<div class="post-metadata">

**Author:** ![DayDreamer-3d](https://ziggit.dev/letter_avatar_proxy/v4/letter/d/f19dbf/32.png) [@DayDreamer-3d](https://ziggit.dev/u/DayDreamer-3d)\
**Post date:** [December 24, 2025, 1:39am UTC](https://ziggit.dev/t/trouble-concatenating-strings-using-an-allocator/13632/1 "2025-12-24T01:39:58Z")

</div>

Hello Everyone,

newbie here coming to zig from a high level language like `python` and I am trying to concatenate strings at the runtime using an allocator and have the below function, however the call is running into `error{OutOfMemory}![]u8`.

```zig
const std = @import("std");

fn cocat_strings(str1: []const u8, str2: []const u8) u8 {
    var gpa = std.heap.GeneralPurposeAllocator(.{}){};
    const allocator = gpa.allocator();
    defer _ = gpa.deinit();
    const combined = std.mem.concat(allocator, u8, &.{ str1, str2 });
    defer allocator.free(combined);
    return combined;
}

```

the caller looks like below

```zig
pub fn main() void {

    const name: *const [3:0]u8 = "Som";
    cocat_strings(name, name); // looking for a result like "SomSom"
}

```

Any help with some explanation would be really appreciated.  
Also, if someone can outline a few good resources on strings in zig that will be great.

Cheers,  
DD.

---

<div class="post-metadata">

**Author:** ![anon47052109](https://ziggit.dev/letter_avatar_proxy/v4/letter/a/71c47a/32.png) [@anon47052109](https://ziggit.dev/u/anon47052109)\
**Post date:** [December 24, 2025, 1:53am UTC](https://ziggit.dev/t/trouble-concatenating-strings-using-an-allocator/13632/2 "2025-12-24T01:53:11Z")

</div>

~~ㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤ~~

---

<div class="post-metadata">

**Author:** ![DayDreamer-3d](https://ziggit.dev/letter_avatar_proxy/v4/letter/d/f19dbf/32.png) [@DayDreamer-3d](https://ziggit.dev/u/DayDreamer-3d)\
**Post date:** [December 24, 2025, 2:22am UTC](https://ziggit.dev/t/trouble-concatenating-strings-using-an-allocator/13632/3 "2025-12-24T02:22:54Z")

</div>

in addition to this I can also take an `allocator: std.memory.Allocator` as an argument and `free and `deinit outside of the function.  
Your solution has worked , cheers.

---

<div class="post-metadata">

**Author:** ![anon47052109](https://ziggit.dev/letter_avatar_proxy/v4/letter/a/71c47a/32.png) [@anon47052109](https://ziggit.dev/u/anon47052109)\
**Post date:** [December 24, 2025, 3:01am UTC](https://ziggit.dev/t/trouble-concatenating-strings-using-an-allocator/13632/4 "2025-12-24T03:01:02Z")

</div>

~~ㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤ~~

---

<div class="post-metadata">

**Author:** ![vulpesx](https://ziggit.dev/user_avatar/ziggit.dev/vulpesx/32/3989_2.png) [@vulpesx](https://ziggit.dev/u/vulpesx)\
**Post date:** [December 24, 2025, 3:04am UTC](https://ziggit.dev/t/trouble-concatenating-strings-using-an-allocator/13632/5 "2025-12-24T03:04:59Z")

</div>

> [@anon47052109](#):
>
> initialize an allocator for the whole module.

Generally _don’t_ do this.

---

<div class="post-metadata">

**Author:** ![Zambyte](https://ziggit.dev/user_avatar/ziggit.dev/zambyte/32/4977_2.png) [@Zambyte](https://ziggit.dev/u/Zambyte)\
**Post date:** [December 24, 2025, 4:27am UTC](https://ziggit.dev/t/trouble-concatenating-strings-using-an-allocator/13632/6 "2025-12-24T04:27:07Z")

</div>

The return type of `std.mem.concat` is (in this case) `error{OutOfMemory}![]u8`. You declare `combined` as the direct result of this function call, meaning the type of `combined` is `error{OutOfMemory}![]u8`. You then pass `combined` to `free`, but that fails because `free` doesn’t expect an error union like that.

You should handle the possible error from calling `concat` by either using `catch` to handle the error directly, `try` to return the error (equivalent to `catch |err| return err`), or use `if`/`else` to conditionally handle the error. Likely you want to use `try`.

---

<div class="post-metadata">

**Author:** ![andrewrk](https://ziggit.dev/user_avatar/ziggit.dev/andrewrk/32/7011_2.png) [@andrewrk](https://ziggit.dev/u/andrewrk)\
**Post date:** [December 24, 2025, 7:59am UTC](https://ziggit.dev/t/trouble-concatenating-strings-using-an-allocator/13632/7 "2025-12-24T07:59:33Z")

</div>

If you’re doing a bunch of string manipulation it’s a good use case for arena allocation. It will help you reduce how many resources you are juggling from many to 1. Start with just one big arena for everything - you can initialize it in main(), and then if you end up needing to free any of that stuff before program exit, then you can introduce more memory management. If you’re just making a CLI tool you probably don’t need anything beyond a single arena allocator for 100% of your memory allocations over the life of the entire program.

---

<div class="post-metadata">

**Author:** ![pierrelgol](https://ziggit.dev/user_avatar/ziggit.dev/pierrelgol/32/10233_2.png) [@pierrelgol](https://ziggit.dev/u/pierrelgol)\
**Post date:** [December 24, 2025, 8:53am UTC](https://ziggit.dev/t/trouble-concatenating-strings-using-an-allocator/13632/8 "2025-12-24T08:53:40Z")

</div>

Hey :), This is the corrected version of your program, the first thing that has changed is the signature of the function, although not mandatory, it’s usually recommended for both clarity and consistency to have each function that requires memory allocation to accept an allocator parameter, even if you don’t care about being idiomatic, it’s still convenient to be able to pass any allocator.

Second the function signature was incorrect, you see concat can return an error, and a string in Zig is just a slice of u8, therefore the correct return type should be `![]u8`, lastly in the main function I show you one way you can transform a `![]u8` into a `[]u8` which is done by catching the error path and handling it.

```zig
const std = @import("std");

fn cocat_strings(allocator: std.mem.Allocator, str1: []const u8, str2: []const u8) ![]u8 {
    return try std.mem.concat(allocator, u8, &.{ str1, str2 });
}

pub fn main() void {
    var gpa = std.heap.GeneralPurposeAllocator(.{}){};
    defer _ = gpa.deinit();

    const allocator = gpa.allocator();

    const name = "Som";
    const my_string = cocat_strings(allocator, name, name) catch |err| {
        return std.debug.print("Fatal : {}\n", .{err});
    };
    defer allocator.free(my_string);
    std.debug.print("result : {s}\n", .{my_string});
}

```

---

<div class="post-metadata">

**Author:** ![tholmes](https://ziggit.dev/user_avatar/ziggit.dev/tholmes/32/5641_2.png) [@tholmes](https://ziggit.dev/u/tholmes)\
**Post date:** [December 24, 2025, 9:44am UTC](https://ziggit.dev/t/trouble-concatenating-strings-using-an-allocator/13632/9 "2025-12-24T09:44:01Z")

</div>

If you’re okay with potentially losing non-printable characters, you can use [std.fmt.allocPrint](https://ziglang.org/documentation/0.15.2/std/#std.fmt.allocPrint):

```zig
pub fn main() !void {
  var gpa = std.heap.GeneralPurposeAllocator(.{}){};
  const allocator = gpa.allocator();

  const name: []const u8 = "Som";
  const name_concat = try std.fmt.allocPrint(allocator, "{s}{s}", .{name, name});
  defer allocator.free(name_concat);

  std.log.info("Concatenated name: {s}", .{name_concat});
}

```

---

<div class="post-metadata">

**Author:** ![DayDreamer-3d](https://ziggit.dev/letter_avatar_proxy/v4/letter/d/f19dbf/32.png) [@DayDreamer-3d](https://ziggit.dev/u/DayDreamer-3d)\
**Post date:** [December 24, 2025, 1:06pm UTC](https://ziggit.dev/t/trouble-concatenating-strings-using-an-allocator/13632/10 "2025-12-24T13:06:44Z")

</div>

Hey Andrew,

thanks for the reply, I was thinking on the same line and end up with GPA being the base allocator and arena being the main allocator like below. I did not share it here before as I do not want to confuse newbies like me.

```zig
const std = @import("std");

fn cocat_strings(allocator: std.mem.Allocator, str1: []const u8, str2: []const u8) error{OutOfMemory}![]const u8 {
    return try std.mem.concat(allocator, u8, &.{ str1, str2 });
}

pub fn main() !void {
    const name: *const [3:0]u8 = "Som";
    const direct_slice: []const u8 = "Test";
    const name_slice = name[0..];

    // create base allocator to do actual work
    var gpa = std.heap.GeneralPurposeAllocator(.{}){};
    const base_allocator = gpa.allocator();

    // create arena allocator to reuse the same memory
    var arena = std.heap.ArenaAllocator.init(base_allocator);
    defer _ = arena.deinit();
    const allocator = arena.allocator();

    var combined = try cocat_strings(allocator, name, name);
    std.debug.print("concat string: `{s}`\n", .{combined});

    combined = try cocat_strings(allocator, name_slice, direct_slice);
    std.debug.print("concat2 string: `{s}`\n", .{combined});
}

```

Cheers,  
DD.

---

<div class="post-metadata">

**Author:** ![andrewrk](https://ziggit.dev/user_avatar/ziggit.dev/andrewrk/32/7011_2.png) [@andrewrk](https://ziggit.dev/u/andrewrk)\
**Post date:** [December 24, 2025, 8:03pm UTC](https://ziggit.dev/t/trouble-concatenating-strings-using-an-allocator/13632/11 "2025-12-24T20:03:01Z")

</div>

`concat(allocator, u8, name, name)` is shorter than `cocat_strings(allocator, name, name)`. You could just `const concat = std.mem.concat;` rather than defining the `cocat_strings` function.

---

<div class="post-metadata">

**Author:** ![Validark](https://ziggit.dev/user_avatar/ziggit.dev/validark/32/646_2.png) [@Validark](https://ziggit.dev/u/Validark)\
**Post date:** [December 24, 2025, 8:28pm UTC](https://ziggit.dev/t/trouble-concatenating-strings-using-an-allocator/13632/12 "2025-12-24T20:28:28Z")

</div>

Come on. Don’t give a newbie a `catch unreachable`. Nobody should use that feature until they actually know what they’re doing.

---

<div class="post-metadata">

**Author:** ![andrewrk](https://ziggit.dev/user_avatar/ziggit.dev/andrewrk/32/7011_2.png) [@andrewrk](https://ziggit.dev/u/andrewrk)\
**Post date:** [December 24, 2025, 9:36pm UTC](https://ziggit.dev/t/trouble-concatenating-strings-using-an-allocator/13632/13 "2025-12-24T21:36:46Z")

</div>

Agreed. It’s also clearly and obviously incorrect here.

[Shoutouts to myself seven years ago](https://youtu.be/Z4oYSByyRak?t=298)

---

<div class="post-metadata">

**Author:** ![anon47052109](https://ziggit.dev/letter_avatar_proxy/v4/letter/a/71c47a/32.png) [@anon47052109](https://ziggit.dev/u/anon47052109)\
**Post date:** [December 24, 2025, 9:41pm UTC](https://ziggit.dev/t/trouble-concatenating-strings-using-an-allocator/13632/14 "2025-12-24T21:41:04Z")

</div>

~~ㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤ~~

---

<div class="post-metadata">

**Author:** ![anon47052109](https://ziggit.dev/letter_avatar_proxy/v4/letter/a/71c47a/32.png) [@anon47052109](https://ziggit.dev/u/anon47052109)\
**Post date:** [December 24, 2025, 9:46pm UTC](https://ziggit.dev/t/trouble-concatenating-strings-using-an-allocator/13632/15 "2025-12-24T21:46:24Z")

</div>

~~ㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤ~~

---

<div class="post-metadata">

**Author:** ![Validark](https://ziggit.dev/user_avatar/ziggit.dev/validark/32/646_2.png) [@Validark](https://ziggit.dev/u/Validark)\
**Post date:** [December 24, 2025, 9:52pm UTC](https://ziggit.dev/t/trouble-concatenating-strings-using-an-allocator/13632/16 "2025-12-24T21:52:25Z")

</div>

You can also just run out of memory if you use it all.

---

<div class="post-metadata">

**Author:** ![Validark](https://ziggit.dev/user_avatar/ziggit.dev/validark/32/646_2.png) [@Validark](https://ziggit.dev/u/Validark)\
**Post date:** [December 25, 2025, 12:21am UTC](https://ziggit.dev/t/trouble-concatenating-strings-using-an-allocator/13632/17 "2025-12-25T00:21:32Z")

</div>

I actually still send people that talk!
