# Exercises

### Exercises

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:

```zig
fn allocBytes(allocator: std.mem.Allocator, len: usize) ![]u8
```

The 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:

```zig
fn allocCopy(allocator: std.mem.Allocator, source: []const u8) ![]u8
```

The 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`.

```zig
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:

```zig
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:

```zig
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:

```zig
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`:

```zig
fn fill(self: *Buffer, value: u8) void
```

The method should fill the owned memory with `value`.

Exercise 12-42. Add a method to `Buffer`:

```zig
fn print(self: *const Buffer) void
```

The method should print the length and first byte of the buffer.

Exercise 12-43. Write a function that borrows a slice:

```zig
fn countByte(bytes: []const u8, needle: u8) usize
```

It 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:

```zig
fn consume(allocator: std.mem.Allocator, bytes: []u8) void
```

After 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.

