diff --git a/include/mempool.h b/include/mempool.h new file mode 100644 index 0000000..4dd9e7e --- /dev/null +++ b/include/mempool.h @@ -0,0 +1,26 @@ +/** + * @file mempool.h + * @author wenjf (Orig5826@163.com) + * @brief + * @version 0.1 + * @date 2026-05-17 + * + * @copyright Copyright (c) 2026 + * + */ +#ifndef _MEMPOOL_H_ +#define _MEMPOOL_H_ + +#include "unicstl_internal.h" + +#ifdef UNICSTL_MALLOC_CUSTOM +extern void *unicstl_malloc(size_t size); +extern void *unicstl_calloc(size_t num, size_t size); +extern void *unicstl_realloc(void *ptr, size_t size); +extern void unicstl_free(void *ptr); +#endif + +void mempool_init(void); +void mempool_deinit(void); + +#endif // _MEMPOOL_H_ diff --git a/include/unicstl.h b/include/unicstl.h index c361fc5..3ee72f8 100644 --- a/include/unicstl.h +++ b/include/unicstl.h @@ -13,6 +13,8 @@ #include "unicstl_internal.h" +#include "mempool.h" + #include "darray.h" #include "linklist.h" #include "dlinklist.h" diff --git a/include/unicstl_config.h b/include/unicstl_config.h index afb691f..e68d5f0 100644 --- a/include/unicstl_config.h +++ b/include/unicstl_config.h @@ -37,7 +37,7 @@ * */ #define UNICSTL_MALLOC_ENABLE // malloc enable -// #define UNICSTL_MALLOC_CUSTOM // malloc custom support +#define UNICSTL_MALLOC_CUSTOM // malloc custom support /** diff --git a/mk.bat b/mk.bat index 3b97976..25e5ffb 100644 --- a/mk.bat +++ b/mk.bat @@ -1,6 +1,8 @@ @REM D:\Lang\cmake-3.27.5-windows-x86_64\bin\cmake.EXE --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=Debug -DCMAKE_EXPORT_COMPILE_COMMANDS:BOOL=TRUE -DCMAKE_C_COMPILER:FILEPATH=D:\Software\mingw64\bin\gcc.exe -DCMAKE_CXX_COMPILER:FILEPATH=D:\Software\mingw64\bin\g++.exe -SF:/OpenDemo/1_vsc_cmake -Bf:/OpenDemo/1_vsc_cmake/build -G "MinGW Makefiles" @REM cmake -Bbuild -G "Visual Studio 17 2022" +del ".\build\release\bin\test.exe" + cmake -B build -G "MinGW Makefiles" @REM cmake -B build -G "Unix Makefiles" diff --git a/src/darray.c b/src/darray.c index b62bea7..4851354 100644 --- a/src/darray.c +++ b/src/darray.c @@ -221,10 +221,7 @@ const void *darray_iter_next(struct _iterator *iter) { iter->_index = iter->_index - 1; } - return obj_at(self->obj, index, self->_obj_size); - - // log_debug("index:%zu", index); - // return self->at(self->obj, index); // TODO: 这里有问题,结构体指针都崩了 + return self->at(self, index); } iterator_t darray_iter(struct _darray *self, linear_order_t order) diff --git a/src/mempool.c b/src/mempool.c new file mode 100644 index 0000000..795c91f --- /dev/null +++ b/src/mempool.c @@ -0,0 +1,90 @@ +/** + * @file mempool.c + * @author wenjf (Orig5826@163.com) + * @brief + * @version 0.1 + * @date 2026-05-17 + * + * @copyright Copyright (c) 2026 + * + */ +#include "mempool.h" + +#ifdef UNICSTL_MALLOC_CUSTOM + +typedef struct _mempool +{ + size_t count_total; + size_t count_free; + + size_t count_malloc; + size_t count_calloc; + size_t count_realloc; +}mempool_t; + +static mempool_t mempool; + + +void mempool_init() +{ + memset(&mempool, 0, sizeof(mempool_t)); +} + +void mempool_deinit() +{ + printf("\n------------------------------ \n"); + printf("count_total: %zu\n", mempool.count_total); + printf("count_free: %zu\n", mempool.count_free); + printf("count_malloc: %zu\n", mempool.count_malloc); + printf("count_calloc: %zu\n", mempool.count_calloc); + printf("count_realloc: %zu\n", mempool.count_realloc); + + size_t leak = mempool.count_total - mempool.count_free; + if (mempool.count_total > mempool.count_free) + { + printf("\nERROR: maybe leak: %zu\n", leak); + } + else if (mempool.count_total < mempool.count_free) + { + printf("\nERROR: maybe free too many\n"); + } + else + { + printf("\nOK: no leak\n"); + } + memset(&mempool, 0, sizeof(mempool_t)); +} + +void *unicstl_malloc(size_t size) +{ + mempool.count_malloc++; + mempool.count_total++; + return malloc(size); +} + +void *unicstl_calloc(size_t num, size_t size) +{ + mempool.count_calloc++; + mempool.count_total++; + return calloc(num, size); +} + +void *unicstl_realloc(void *ptr, size_t size) +{ + mempool.count_realloc++; + if(ptr == NULL) + { + mempool.count_total++; + } + return realloc(ptr, size); +} + +void unicstl_free(void *ptr) +{ + if (ptr != NULL) + { + mempool.count_free++; + free(ptr); + } +} +#endif diff --git a/src/segarray.c b/src/segarray.c index a50a629..8cc2dc3 100644 --- a/src/segarray.c +++ b/src/segarray.c @@ -432,22 +432,33 @@ static bool segarray_clear(struct _segarray *self) static void segarray_destory(struct _segarray *self) { unicstl_assert(self != NULL); - ringbuf_t map = self->_map; - if (self->_dynamic && map != NULL) + ringbuf_t map_used[2] = { + self->_map, + self->_mapfree + }; + + if(self->_dynamic == true) { rawbuf_t seg = NULL; - while(!map->empty(map)) + + ringbuf_t map = self->_map; + for(size_t i = 0; i < 2; i++) { - if (map->pop_back(map, &seg)) + map = map_used[i]; + while(!map->empty(map)) { - if(seg == NULL) + if (map->pop_back(map, &seg)) { - log_error("seg is NULL"); + if(seg == NULL) + { + log_error("seg is NULL"); + } + rawbuf_free(&seg); } - rawbuf_free(&seg); } } ringbuf_free(&self->_map); + ringbuf_free(&self->_mapfree); } log_debug("segarray destoryed!"); } @@ -540,11 +551,10 @@ iterator_t segarray_iter(struct _segarray *self, linear_order_t order) * @param self * @param obj_size * @param capacity - * @param mem_pool !!! mem_pool_size = capacity * obj_size * @return true * @return false */ -bool segarray_init(struct _segarray *self, size_t obj_size, size_t capacity, void *mem_pool) +static bool segarray_init(struct _segarray *self, size_t obj_size, size_t capacity) { unicstl_assert(self != NULL); unicstl_assert(obj_size > 0); @@ -555,53 +565,6 @@ bool segarray_init(struct _segarray *self, size_t obj_size, size_t capacity, voi self->_capacity = capacity; self->_segsize = capacity; - if (mem_pool != NULL) - { - self->obj = (char *)mem_pool; - self->_dynamic = false; - } - else - { - self->_dynamic = true; - - self->_map = ringbuf_new(sizeof(rawbuf_t), 8); - if (self->_map == NULL) - { - log_warn("self->_map new failed!"); - return false; - } - - self->_mapfree = ringbuf_new(sizeof(rawbuf_t), 8); - if (self->_mapfree == NULL) - { - log_warn("self->_mapfree new failed!"); - ringbuf_free(&self->_map); - return false; - } - - rawbuf_t seg = rawbuf_new(obj_size, self->_segsize); - if (seg == NULL) - { - log_warn("seg new failed!"); - ringbuf_free(&self->_map); - ringbuf_free(&self->_mapfree); - return false; - } - // config first obj index in seg array - self->_seghead = clac_start_index(self->_segsize); - self->_segtail = self->_seghead; - - // add first seg array to map - if(!self->_map->push_back(self->_map, &seg)) - { - log_warn("self->_map push back failed!"); - rawbuf_free(&seg); - ringbuf_free(&self->_map); - ringbuf_free(&self->_mapfree); - return false; - } - } - self->_destory = segarray_destory; // -------------------- public -------------------- @@ -635,6 +598,46 @@ bool segarray_init(struct _segarray *self, size_t obj_size, size_t capacity, voi // -------------------- debug -------------------- self->print = segarray_print; + // -------------------- memory -------------------- + + self->_dynamic = true; + + self->_map = ringbuf_new(sizeof(rawbuf_t), 8); + if (self->_map == NULL) + { + log_warn("self->_map new failed!"); + return false; + } + + self->_mapfree = ringbuf_new(sizeof(rawbuf_t), 8); + if (self->_mapfree == NULL) + { + log_warn("self->_mapfree new failed!"); + ringbuf_free(&self->_map); + return false; + } + + rawbuf_t seg = rawbuf_new(obj_size, self->_segsize); + if (seg == NULL) + { + log_warn("seg new failed!"); + ringbuf_free(&self->_map); + ringbuf_free(&self->_mapfree); + return false; + } + // config first obj index in seg array + self->_seghead = clac_start_index(self->_segsize); + self->_segtail = self->_seghead; + + // add first seg array to map + if(!self->_map->push_back(self->_map, &seg)) + { + log_warn("self->_map push back failed!"); + rawbuf_free(&seg); + ringbuf_free(&self->_map); + ringbuf_free(&self->_mapfree); + return false; + } return true; } @@ -648,7 +651,7 @@ segarray_t segarray_new(size_t obj_size, size_t capacity) return NULL; } - if (segarray_init(segarray, obj_size, capacity, NULL) != true) + if (segarray_init(segarray, obj_size, capacity) != true) { log_warn("segarray init failed"); unicstl_free(segarray); diff --git a/test/test.c b/test/test.c index cfc6a70..863d6d1 100644 --- a/test/test.c +++ b/test/test.c @@ -75,10 +75,11 @@ void tearDown(void) int main(int argc, char const *argv[]) { - log_init(); - printf("----- Unicstl Unit Test -----\n"); UNITY_BEGIN(); + + log_init(); + mempool_init(); TEST_ADD(test_unicstl); @@ -94,15 +95,15 @@ int main(int argc, char const *argv[]) TEST_ADD(test_queue); TEST_ADD(test_stack); - // TEST_ADD(test_list); - // TEST_ADD(test_heap); + TEST_ADD(test_list); + TEST_ADD(test_heap); // TEST_ADD(test_tree); // TEST_ADD(test_graph); TEST_ADD(test_segarray); - TEST_ADD(test_arraylist); + mempool_deinit(); log_deinit(); return UNITY_END(); } diff --git a/test/test_arraylist.c b/test/test_arraylist.c index 942bdeb..1fbc4f3 100644 --- a/test/test_arraylist.c +++ b/test/test_arraylist.c @@ -395,6 +395,8 @@ static void test_arraylist_at(void) p_int = arraylist->at(arraylist, 9); TEST_ASSERT_EQUAL_INT(10, *p_int); + + arraylist_free(&arraylist); } static void test_arraylist_at_negative(void) @@ -420,6 +422,8 @@ static void test_arraylist_at_negative(void) p_int = arraylist->at(arraylist, -1); TEST_ASSERT_EQUAL_INT(10, *p_int); + + arraylist_free(&arraylist); } static void test_arraylist_at_invalid(void)