# Panic: Invalid free when freeing a struct's allocated memory

**URL:** <https://ziggit.dev/t/panic-invalid-free-when-freeing-a-structs-allocated-memory/8280>\
**Category:** Help\
**Tags:** memory-management\
**Created:** [January 31, 2025, 4:17pm UTC](https://ziggit.dev/t/panic-invalid-free-when-freeing-a-structs-allocated-memory/8280 "2025-01-31T16:17:31Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![nicolasb](https://ziggit.dev/user_avatar/ziggit.dev/nicolasb/32/4424_2.png) [@nicolasb](https://ziggit.dev/u/nicolasb)\
**Post date:** [January 31, 2025, 4:17pm UTC](https://ziggit.dev/t/panic-invalid-free-when-freeing-a-structs-allocated-memory/8280/1 "2025-01-31T16:17:31Z")

</div>

Hi everyone,

I’m building a struct with two fields (for now) `[]const i64` and `[]const u8` (plus the allocator).  
Everything works, tests passes BUT freeing the `[]const u8` panics:

```zig
thread 165960 panic: Invalid free
/usr/lib/zig/std/heap/general_purpose_allocator.zig:652:21: 0x1048fac in freeLarge (test)
                    @panic("Invalid free");
                    ^
/usr/lib/zig/std/heap/general_purpose_allocator.zig:865:31: 0x104415c in free (test)
                self.freeLarge(old_mem, log2_old_align, ret_addr);

```

I’ve spent two days trying to understand that with no success.

- the panic message does not give me a lot of information
- it does not seem to be related to data size or alignment
- in the source code of the freeLarge function (general\_purpose\_allocator.zig), I can imagine why it panics (no entry in the allocations table), but that does not help me neither
- if I remove the `free` for the u8 slice, that works but of course indicates there’s a memory leak

Here is the struct and deinit definitions:

```zig
const Tz = struct {
    /// Allocator
    allocator: std.mem.Allocator,
    /// transition times timestamps table
    tzh_timecnt_data: []const i64,
    // indices for the next field
    tzh_timecnt_indices: []const u8,
    // a struct containing UTC offset, daylight saving time, abbreviation index
    //tzh_typecnt: []const Ttinfo,
    // abbreviations table
    //tz_abbr: []const u8),

    pub fn deinit(self: *const Tz) void {
        self.allocator.free(self.tzh_timecnt_data);
        self.allocator.free(self.tzh_timecnt_indices);
    }
};

```

If needed, the complete source is there:

> **[GitHub - nicolasbauw/tzfile at dev](https://github.com/nicolasbauw/tzfile/tree/dev)**
>
> dev

I’m new at Zig, this is a learning project; porting a library I wrote previously in another language.  
Until now I found answers to all my questions, but with this one I’m stuck 🙂  
I would greatly appreciate some help !

---

<div class="post-metadata">

**Author:** ![IntegratedQuantum](https://ziggit.dev/user_avatar/ziggit.dev/integratedquantum/32/782_2.png) [@IntegratedQuantum](https://ziggit.dev/u/IntegratedQuantum)\
**Post date:** [January 31, 2025, 4:28pm UTC](https://ziggit.dev/t/panic-invalid-free-when-freeing-a-structs-allocated-memory/8280/2 "2025-01-31T16:28:15Z")

</div>

First up, before I get to the actual problem, a note on debugging errors like this:  
Invalid free means that you are trying to free data that was never allocated with that allocator.  
So in order to figure out the error, you need to trace back the source of the allocation, being `tzh_timecnt_indices`, in the code.

This leads us to the following piece of code:

```zig
    var tzh_timecnt_indices = try allocator.alloc(u8, tzh_timecnt_len);
    errdefer allocator.free(tzh_timecnt_indices);

    tzh_timecnt_indices = buffer[HEADER_LEN + header.v2_header_start + header.tzh_timecnt * 8 .. tzh_timecnt_end];

    // Returning the Tz struct
    return Tz{ .allocator = allocator, .tzh_timecnt_data = tzh_timecnt_data, .tzh_timecnt_indices = tzh_timecnt_indices };

```

The first red flag is `var tzh_timecnt_indices`, if you allocate something, then you don’t want to change the pointer again, only the thing it’s pointing to, so it should be const.

And you do overwrite the pointer with `tzh_timecnt_indices = buffer[...];`  
After this line, `tzh_timecnt_indices` no longer points to the allocated memory, instead it points into `buffer` which is a temporary piece of memory.

If you want to copy the values inside the buffer into the newly allocated memory, then you should use `@memcpy` instead.

---

<div class="post-metadata">

**Author:** ![nicolasb](https://ziggit.dev/user_avatar/ziggit.dev/nicolasb/32/4424_2.png) [@nicolasb](https://ziggit.dev/u/nicolasb)\
**Post date:** [January 31, 2025, 5:29pm UTC](https://ziggit.dev/t/panic-invalid-free-when-freeing-a-structs-allocated-memory/8280/3 "2025-01-31T17:29:26Z")

</div>

Thanks a lot ! That easily solved my problem 🙂
