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.
In cocat_strings you use defer allocator.free(combined); that is executed when the scope (your function) exists.
What is expected is that you return the string you have just created. Your function should look something like:
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.
Yeah, you can. Or you do your module to handle strings and you initialize an allocator for the whole module.
Strings are a good exercise for newbies like us to to get acquainted to the language. Start with:
and write hundreds of functions to handle strings: concatenation, converting to and from numbers, to and from cstrings, writing to and from file … for some you will want to use allocator.realloc.
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.
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.
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.
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.
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});
}
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.
Hope your metric applies to me
Excited to know that in 7 years I will be sharp.
Reading the quality ziggit answers make feel pretty dumb sometimes (most of the time ?).