The exercises in this section are meant to make allocation habits precise. Each one should be written as a complete program unless stated otherwise.
The exercises in this section are meant to make allocation habits precise. Each one should be written as a complete program unless stated otherwise.
Exercise 12-25. Allocate a slice of 16 u8 values with std.heap.page_allocator. Fill it with zeroes. Print its length. Free it before the program exits.
Exercise 12-26. Allocate a slice of 8 i32 values. Store the values 0 through 7 in it. Print the slice with {any}.
Exercise 12-27. Write a function:
fn allocBytes(allocator: std.mem.Allocator, len: usize) ![]u8The function should allocate len bytes, set them all to zero, and return the slice. The caller must free the returned memory.
Exercise 12-28. Write a function:
fn allocCopy(allocator: std.mem.Allocator, source: []const u8) ![]u8The function should allocate a new byte slice and copy source into it. The caller must own the copy.
Exercise 12-29. Create a std.heap.GeneralPurposeAllocator in main. Pass its allocator to a function named run. Do all heap allocation inside run.
Exercise 12-30. Write a program that allocates one Point value with allocator.create.
const Point = struct {
x: i32,
y: i32,
};Set both fields, print them, and destroy the value.
Exercise 12-31. Write a program that uses std.ArrayList(u32). Append the numbers 1 through 10. Print their sum. Call deinit.
Exercise 12-32. Rewrite Exercise 12-31 so the ArrayList receives its allocator from a run function parameter.
Exercise 12-33. Create an arena allocator. Allocate three byte slices from it. Do not free them individually. Release all memory by deinitializing the arena.
Exercise 12-34. Use an arena allocator to build a temporary list of strings. Print the strings. Free the arena at the end.
Exercise 12-35. Explain why this function is invalid:
fn bad(parent_allocator: std.mem.Allocator) ![]u8 {
var arena = std.heap.ArenaAllocator.init(parent_allocator);
defer arena.deinit();
const allocator = arena.allocator();
return try allocator.dupe(u8, "zig");
}Exercise 12-36. Fix Exercise 12-35 by allocating the returned string from the caller’s allocator instead of from a local arena.
Exercise 12-37. Create a fixed-buffer allocator backed by this array:
var memory: [512]u8 = undefined;Allocate two slices from it and print their lengths.
Exercise 12-38. Use std.ArrayList(u8) with a fixed-buffer allocator. Append "hello" and " zig", then print the resulting string.
Exercise 12-39. Create a fixed-buffer allocator with only 8 bytes of backing storage. Attempt to allocate 1024 bytes. Handle the allocation error with catch.
Exercise 12-40. Write a small owned type:
const Buffer = struct {
allocator: std.mem.Allocator,
data: []u8,
fn init(allocator: std.mem.Allocator, len: usize) !Buffer {
// ...
}
fn deinit(self: *Buffer) void {
// ...
}
};init should allocate the buffer. deinit should free it.
Exercise 12-41. Add a method to Buffer:
fn fill(self: *Buffer, value: u8) voidThe method should fill the owned memory with value.
Exercise 12-42. Add a method to Buffer:
fn print(self: *const Buffer) voidThe method should print the length and first byte of the buffer.
Exercise 12-43. Write a function that borrows a slice:
fn countByte(bytes: []const u8, needle: u8) usizeIt should not allocate and should not free memory.
Exercise 12-44. Write a function that takes ownership of an allocated slice and frees it before returning:
fn consume(allocator: std.mem.Allocator, bytes: []u8) voidAfter calling consume, the caller must not use the slice.
Exercise 12-45. Write a program with one allocation bug. Then fix it. Examples: leaked memory, double free, use after free, or returning a slice to local memory.
Exercise 12-46. Write a short note explaining the difference between owning a slice and borrowing a slice.
Exercise 12-47. Write a short note explaining when to use an arena allocator.
Exercise 12-48. Write a short note explaining when to use a fixed-buffer allocator.
Exercise 12-49. Write a short note explaining why library functions should usually accept an allocator instead of choosing std.heap.page_allocator internally.
Exercise 12-50. Write a complete program that reads command-line arguments into an ArrayList([]const u8) and prints them.