Investigating the reason of "Bad free" when running tests. Do I use Arena's incorrectly?

I’ll preface my question with a notice that I’m only starting to learn manual memory management strategies (arenas,etc).

I have the proc which looks like this:

gen_bytes :: proc(allocator: Allocator) {
  // ...snip...
  rand_bytes :=  make([]u8, size, allocator)
  defer delete(rand_bytes)

  crypto.rand_bytes(rand_bytes)
  // ...snip...
}

and then I have a @(test) which calls this function, but for some reason I always get “bad free” reported:

@(test)
test_gen :: proc(t: ^testing.T) {
  gen_bytes(context.temp_allocator)
  free_all(context.temp_allocator)
}

Running this test I get

 +++ bad free        @ 0x7FB26EE88F79
    (+info pointing to the line with  the 'delete')

I tried to replace allocator with my own Dynamic_Arena-allocator but got the same error.

The only thing that helps is not using passed allocator in gen_bytes in that make call, but this uses a heap allocator. What if I don’t want to use the heap there?

Is this error there because both times I’ve used arena allocators and they do not support individual free’s?

Should I just use context.temp_allocator and remove that delete? But what if context.temp_allocator gets replaced with something which requires individual free’s?

How is this usually handled in big and serious projects/libraries?

You must pass the same allocator to delete as to any procedure which allocates. make(..., allocator) and delete(..., allocator) are a pair, as are new(..., allocator) and free(..., allocator).

By default, these procedures use the context.allocator if the argument is not supplied. Your example would work in a subtle way if the allocator passed was the context allocator, and that might be a hard bug to catch for a newbie.

2 Likes

Oh wow, now it seems such an obvious mistake! Thanks! Until now I usually wrote some medium to small one-off programs, so I just didn’t think of properly freeing memory, used the default ones in context, I even forgot that delete also takes an allocator which is quite logical.