Compare commits

...

2 Commits

Author SHA1 Message Date
En Yi e70baef781 Add sample for string map 2024-12-30 22:44:06 +08:00
En Yi 690e705c94 Add test for invalid freeing 2024-12-30 22:43:58 +08:00
3 changed files with 47 additions and 3 deletions

View File

@ -74,7 +74,7 @@ void mem_arena_print()
printf("O1heap Memory Arena Info\n");
printf("--------------------\n");
printf("Capacity: %.3f MB\n", diag.capacity * 1.0 / 1024 / 1024);
printf("Allocated: %.3f MB\n", diag.allocated * 1.0 /1024/1024);
printf("Allocated: %.3f MB (%lu)\n", diag.allocated * 1.0 /1024/1024, diag.allocated);
printf("Peak allocated: %.3f MB\n", diag.peak_allocated * 1.0 /1024/1024);
printf("Peak request: %lu\n", diag.peak_request_size);
printf("OOM count: %lu\n\n", diag.oom_count);
@ -97,14 +97,19 @@ void* mem_arena_malloc(size_t size)
void mem_arena_free(void* ptr)
{
// Because we keep track of the memory alloc'd, we can check if the memory
// being freed has been allocated by the heap.
// The free will be ignored if it is not from the heap.
// This is useful in case you want to mix static and dynamic memory in a component field.
// And you want to universally free the pointer without care.
sc_mutex_lock(&lock);
o1heapFree(heap_handle, ptr);
size_t* sz = cc_get(&mmap, (uintptr_t)ptr);
assert(sz != NULL);
//assert(sz != NULL);
if (sz == NULL) {
return;
}
o1heapFree(heap_handle, ptr);
total_mallocd -= *sz;
assert(cc_erase(&mmap, (uintptr_t)ptr));

View File

@ -1,5 +1,6 @@
#include <stdio.h>
#include "base.h"
#include "memory_arena.h"
#include <assert.h>
int main(void) {
@ -27,6 +28,29 @@ int main(void) {
mem_arena_print();
}
{
cc_map(char*, int) str_map;
cc_init(&str_map);
cc_reserve(&str_map, 4);
mem_arena_print();
{
// For char*, you have to allocated memory (static or dynamic)
char* sample = mem_arena_malloc(4);
memcpy(sample, "lol", 4);
cc_insert(&str_map, sample, 15);
}
int* val = cc_get(&str_map, "lol");
printf("str key get: %p\n", val);
mem_arena_print();
// Need to retrieve char* to free, if it is dynamic
// On retrive, dereference to get point and free
// Safer to NULL check first
// but we know it exists
mem_arena_free((void*)*cc_key_for(&str_map, val));
cc_cleanup(&str_map);
mem_arena_print();
}
{
printf("Map of maps\n");
cc_map(int, cc_map(int,int)) map_of_map;

View File

@ -44,10 +44,25 @@ static void test_simple_malloc(void **state)
assert_int_equal(mem_arena_get_allocated(), 0);
}
static void test_free_unallocated(void **state)
{
(void)state;
int val = 0;
mem_arena_free(&val);
}
static void test_free_null(void **state)
{
(void)state;
mem_arena_free(NULL);
}
int main(void)
{
const struct CMUnitTest tests[] = {
cmocka_unit_test_setup_teardown(test_simple_malloc, setup_mem_arena, teardown_mem_arena),
cmocka_unit_test_setup_teardown(test_free_unallocated, setup_mem_arena, teardown_mem_arena),
cmocka_unit_test_setup_teardown(test_free_null, setup_mem_arena, teardown_mem_arena),
};
return cmocka_run_group_tests(tests, NULL, NULL);