If I were to write a malloc, and I’m sorely tempted….
It would be to address these issues…
A malloc knows about the true size of the block allocated… but doesn’t provide an API to find out.
A malloc knows about the original block size requested…. but rounds it up and forgets it.
An index off the end of a block will corrupt mallocs internal data structures… Good Luck find that. (Valgrind is wonderful…. if you have it on your platform.)
Good luck finding leaks.
Good luck finding use after frees.
A allocator for fixed size blocks wins hands down performance wise over a variable block size allocator.
The samba projects talloc has some pretty compelling features.
It would be a fun exercise, but with the relatively limited API and general purpose requirements it would be hard to do better.
If you could change the API you could add memory pools something like Cocoa has, but with manual releasing.
A allocator for fixed size blocks wins hands down performance wise over a variable block size allocator.
Wins in what terms? If your application always uses 120 byte blocks then you could use a 128 allocations for example, you might get good alignment and cache access, but you are always going to be wasting bytes. And then when you request 20 bytes you waste 108 bytes. So I think allowing multiple allocators could be useful. An application that commonly has 128 and 1024 byte allocations could use something like pool0 for 128 byte blocks, pool1 for 1024 byte blocks and normal malloc for everything else. It would setup the pools first, picking a fixed size for each allocation.
A common use case is a program that does tens of thousands of allocations and deallocations of exactly the same struct.
If you use a variable sized malloc&free you get a substantial overhead to manage fragmentation.
If you create a special allocator that allocates exactly that struct and nothing else… OK, you can’t use it in general, in general you fall back on a standard malloc.
But for the specific case of allocating and deallocating that particular struct, its a a big win. (Although you lose the ability to share that pool of memory with the general users of the heap. But for embedded systems preallocation for the designed for worst case is best practice.
If I were to write a malloc, and I’m sorely tempted….
It would be to address these issues…
It would be a fun exercise, but with the relatively limited API and general purpose requirements it would be hard to do better.
If you could change the API you could add memory pools something like Cocoa has, but with manual releasing.
Wins in what terms? If your application always uses 120 byte blocks then you could use a 128 allocations for example, you might get good alignment and cache access, but you are always going to be wasting bytes. And then when you request 20 bytes you waste 108 bytes. So I think allowing multiple allocators could be useful. An application that commonly has 128 and 1024 byte allocations could use something like pool0 for 128 byte blocks, pool1 for 1024 byte blocks and normal malloc for everything else. It would setup the pools first, picking a fixed size for each allocation.
That isn’t what I mean by fixed size allocator.
A common use case is a program that does tens of thousands of allocations and deallocations of exactly the same struct.
If you use a variable sized malloc&free you get a substantial overhead to manage fragmentation.
If you create a special allocator that allocates exactly that struct and nothing else… OK, you can’t use it in general, in general you fall back on a standard malloc.
But for the specific case of allocating and deallocating that particular struct, its a a big win. (Although you lose the ability to share that pool of memory with the general users of the heap. But for embedded systems preallocation for the designed for worst case is best practice.