Rcmalloc
robust/easy-to-use/fast/low fragmentation c++ memory allocator
Install / Use
/learn @ceorron/RcmallocREADME
rcmalloc - robust/easy-to-use/fast/low fragmentation memory allocator, that allows thread-safe/unthreaded memory pools
Features
- robust, no known bugs or issues
- allocates large blocks that are divided up for individual allocations preventing slow OS calls to malloc/realloc/free
- simple design/binary search/pointer arithmetic ensures fast allocation/reallocation/deallocation
- small, minimal design about 1300 lines of c++ total!!
- returns aligned memory for all types for faster load and store - alignment can be set on per allocation basis
- low fragmentation, uses smallest matching size avaliable on allocation
- smart reallocation function gives lower fragmentation/better locality of reference than default std allocator (using custom vector class) (*)
- thread-safe, when needed
- memory pools - replacement for memory pools that generalises better
- simple type safe alternatives to new/new[] and delete/delete[]
NOTE this is a personal project, the term fast is used loosely here, and it is not recommended you use this in production.
(*) Fast reallocation for custom written vector/growable list class. To improve performance and reduce fragmentation the allocator include a custom smart reallocate function that allows byte movement ranges to be specified from a custom vector class (not included). Allowing fast and efficient memmove calls during reallocation as well as preventing multiple memmoves usually needed by C realloc function if used with a "vector" class.
MIT Licence - See Source/License file
Example use - C++
(examples in main.cpp)
#include <iostream>
#include <vector>
#include "rcmalloc.hpp"
using namespace std;
using namespace rcmalloc;
struct a_struct {
unsigned a = 100;
float b = 3.0;
};
#define POOLB 1
#define POOLC 2
int main() {
//use new/new[] and delete/delete[] replacements
cout << "Test 1" << endl;
{
//allocate, construct
a_struct& a1 = *new_T<a_struct>();
a_struct& a2 = *new_T<a_struct>();
a_struct& a3 = *new_T(a_struct{300, 10.0f});
//allocate, construct list
a_struct* l1 = new_T_array<a_struct>(100);
//destruct deallocate
delete_T(&a1);
delete_T(&a2);
delete_T(&a3);
//destruct deallocate list
delete_T_array(l1, 100);
}
//use allocate/reallocate/deallocate directly
//use new feature of reallocate that allows the efficient movement of memory when reallocating
cout << "Test 2" << endl;
{
default_allocator<a_struct> allctr;
alloc_data allcdt = init_alloc_data<a_struct>();
allcdt.size = 100 * sizeof(a_struct);
a_struct* l2 = (a_struct*)allctr.allocate(&allcdt);
//init the memory in l2
for(unsigned i = 0; i < 100; ++i)
l2[i] = a_struct{700, 8.5f};
//insert 100 elements after element 40
realloc_data rdat = {
/*void* ptr=*/ l2,
/*void* hint=*/ 0,
/*uint32_t from_byte_size=*/ 100 * sizeof(a_struct),
/*uint32_t to_byte_size=*/ 200 * sizeof(a_struct),
/*uint32_t keep_byte_size_1=*/ 40 * sizeof(a_struct),
/*uint32_t keep_byte_size_2=*/ 60 * sizeof(a_struct),
/*int32_t keep_from_byte_offset_1=*/ 0,
/*int32_t keep_from_byte_offset_2=*/ 40 * sizeof(a_struct),
/*int32_t keep_to_byte_offset_1=*/ 0,
/*int32_t keep_to_byte_offset_2=*/ 140 * sizeof(a_struct),
/*uint32_t from_count_1=*/ 40,
/*uint32_t from_count_2=*/ 60,
/*uint32_t alignment=*/ std::alignment_of<a_struct>(),
/*uint32_t size_of=*/ sizeof(a_struct),
/*uint32_t minalignment=*/ std::alignment_of<uintptr_t>(),
/*uint32_t byterounding=*/ sizeof(uintptr_t),
//NOTE *** move_func and intermediary_move_func function pointers can be 0/NULL if std::is_trivially_copyable<a_struct>::value == true ***
/*object_move_func move_func=*/ object_move_generator<a_struct>::object_move,
/*object_move_func intermediary_move_func=*/ object_move_generator<a_struct>::object_intermediary_move,
/*bool istrivial=*/ std::is_trivially_move_constructible<a_struct>::value
};
l2 = (a_struct*)allctr.reallocate(&rdat);
//init the new memory in l2
for(unsigned i = 40; i < 140; ++i)
l2[i] = a_struct{250, 2.5f};
dealloc_data deallcdt = init_dealloc_data<a_struct>();
deallcdt.ptr = l2;
deallcdt.size = 200 * sizeof(a_struct);
allctr.deallocate(&deallcdt);
}
//as smaller global memory pools - with or without threading
//aligns ints to 64 bits
cout << "Test 3" << endl;
{
default_allocator<int, rc_multi_threaded_internal_allocator<std::mutex, ALLOC_PAGE_SIZE, POOLB>> B;
default_allocator<int, rc_internal_allocator<ALLOC_PAGE_SIZE, POOLC>> C;
alloc_data allcdt1 = init_alloc_data<a_struct>();
allcdt1.size = 100 * sizeof(int);
allcdt1.alignment = std::alignment_of<uint64_t>();
int* l3 = (int*)B.allocate(&allcdt1);
alloc_data allcdt2 = init_alloc_data<a_struct>();
allcdt2.size = 100 * sizeof(int);
allcdt2.alignment = std::alignment_of<uint64_t>();
int* l4 = (int*)C.allocate(&allcdt2);
//init memory to 1s
for(unsigned i = 0; i < 100; ++i)
l3[i] = 1;
for(unsigned i = 0; i < 100; ++i)
l4[i] = 1;
dealloc_data deallcdt1 = init_dealloc_data<a_struct>();
deallcdt1.ptr = l3;
deallcdt1.size = 100 * sizeof(int);
deallcdt1.alignment = std::alignment_of<uint64_t>();
B.deallocate(&deallcdt1);
dealloc_data deallcdt2 = init_dealloc_data<a_struct>();
deallcdt2.ptr = l4;
deallcdt2.size = 100 * sizeof(int);
deallcdt2.alignment = std::alignment_of<uint64_t>();
C.deallocate(&deallcdt2);
}
//as replacement for std allocator
cout << "Test 4" << endl;
{
vector<a_struct, default_std_allocator<a_struct>> vec;
vec.push_back(a_struct{800, 45.0f});
vec.push_back(a_struct{350, 30.0f});
vec.push_back(a_struct{180, 72.0f});
}
cout << "End Test" << endl;
return 0;
}
Please use and let me know what you think.
Thanks
ceorron
aka
Richard Cookman
Related Skills
node-connect
344.1kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
96.8kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
344.1kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
qqbot-media
344.1kQQBot 富媒体收发能力。使用 <qqmedia> 标签,系统根据文件扩展名自动识别类型(图片/语音/视频/文件)。
