strlcat / smalloc

SMalloc -- a *static* memory allocator.
MIT License
36 stars 12 forks source link
malloc malloc-free memory-allocation memory-allocator memory-management static

WARNING: THIS CODE IS NOT SUPPORTED ANYMORE. If you considering using it, be aware that the code is not going to be supported.

This code will be left as is. No changes or further development are planned. I planned some features to be implemented in past, but this code itself is not optimized for performance, so I abandoned it.

I can recommend you to try out mimalloc instead, which does exactly what you want: allocation from multiple custom heaps, automatic zeroing, security features, highly tunable for specific task. It's not embedded-friendly tho. So if your code must run inside MCU, it's not what you want.

SMalloc -- a static memory allocator.

SMalloc allows you to use an arbitrary memory array, which is allocated inside your program as, say

static char my_memory[10240]; /* 10kb memory block */

, dynamically - that is, allocate objects of fixed length from it.

Thus, it's like you usually do:

ptr = malloc(strlen(str)+1);
if (!ptr) { ... error handling ... }
... do something with ptr ...
free(ptr);

, but space for "ptr" will be allocated from your my_memory[].

SMalloc has more useful features rather than usual memory allocators available:

SMalloc still will not permit you to do these things however:

But why?

SMalloc is a design decision for my own long term project - access(8). This program had a silly static memory allocator in past, which used large and small static arrays of fixed lengths and this approach was really simple, but too memory wasteful of course. Because super is not so large and does not do much of large memory allocations I seriously thought about brk() style memory allocation, that is - just have a large memory pool and shift an allocation pointer among it until it will not run out of memory of course. But large string allocations and requirement of almost arbitrary string length handling made this idea inadequate.

Time passed, I felt a need for the allocator in my other (security) projects. So I decided finally to sit and write one, even if it will take a month to write. The working prototype however worked after less than two hours of coding :-)

Answering a generic "Why?" question is simple: because almost nobody did that in the past.

Current memory allocators, both supplied with your system and separate libraries rely on these two (or more) things:

The target of this library is to have a preallocated memory since the program start: if program did started, it will have this memory already allocated and unreclaimable, always available. The only problem was to use it as a big memory pool and allocate smaller objects from it instead of opaque size, discontinous heap memory provided by host malloc.

SMalloc also strives to be very simple to understand for beginners who learn C language.

That's why such library should exist.

Who may need it?

SMalloc maybe useful for you, if you need to:

Implementation details

SMalloc search strategy is simple pointer-size or start-length two stage search. First stage searches for any allocated blocks. Second stage searches for blocks beyond found free space.

SMalloc is a very simple allocator. It has no any additional protective features, nor any speedup optimisations. It is NOT suitable for general usage, but only for small projects which require small amounts of allocated objects and small pools.

It's header consists of three numbers:

"Block" is a memory area with header and user data. Free memory can contain anything. The invalid header is considered as free memory during search.

Searches are done by shifting a header-wide pointer across the pool. Allocated block is found by testing each possible header for validity. During primary search allocated blocks are jumped over by their real size number. If free space is found, a secondary search is started for possible end of free space and next allocated block. If no such is found and size marker exceeded user requested size, the free space is turned into block with header and pointer to user data is returned. If during search an allocated block is found prior to user size is hit, then secondary search is aborted, and primary search is resumed. Return of user data aborts primary search obviously.

SMalloc preventively crashes the whole program (by default) in these conditions:

SMalloc cannot work properly with relocated pool itself. The address of allocated objects is encoded into header into tag field and cannot be mass reassigned easily. There will be no support for that.

Conclusion

I hope SMalloc will find it's way into many projects outside of the camp it was developed for. Possible area to use it is an embedded world or other small projects like author's access(8). It may fill the gap or remain mostly unknown, but I hope it will be less buggy in future :-)

SMalloc was written by Andrey "ElectroRys" Rys during Aug2017. Contact: rys@lynxlynx.ru; https://gitlab.com/electrorys

Licensing

SMalloc is MIT licensed: Copyright (c) 2017 Andrey Rys. All rights reserved.

By using it you absolutely, in sane mind, accept that this code can kill your dog, terrorise your mom and finally shock you with 200VDC @ 10mA. Although, obviously, it will not do that and cannot do, but just to warn you of possibility. I do not know, maybe your embedded Arduino will fail with memory allocation and then will turn it's brains insane and send a signal through optocoupler driver to a power MOSFET, which will lead this power to you. Anything then can happen :-)

For full reuse conditions see COPYRIGHT file.