stack->peek把data的内存给修改了,后续再排查一下原因

This commit is contained in:
建峰 2026-05-13 19:27:38 +08:00
parent 2278bad0a4
commit 97653622c1
10 changed files with 94 additions and 353 deletions

View File

@ -13,6 +13,8 @@ flowchart TB
subgraph hal
segarray[segarray<br>大数据扩容优先] --> darray
string --> darray
hashtable --> darray
end
subgraph adapter
@ -27,7 +29,10 @@ flowchart TB
end
subgraph top
tree -.-> stack
tree -.-> queue
rbtree -.-> stack
rbtree -.-> queue
map -.-> rbtree
unordered_map -.-> hashtable
end
```

View File

@ -42,9 +42,11 @@ struct _deque
bool (*front)(struct _deque* self, void* obj);
// base
size_t(*size)(struct _deque* self);
size_t (*size)(struct _deque* self);
size_t (*capacity)(struct _deque* self);
bool (*clear)(struct _deque* self);
bool (*empty)(struct _deque* self);
bool (*full)(struct _deque* self);
// iter
iterator_t (*iter)(struct _deque* self, enum _deque_order order);

View File

@ -18,7 +18,7 @@
#include "unicstl_config.h"
// -------------------- DEBUG CONFIG --------------------
#ifndef LOGGER_ON
#ifdef LOGGER_ON
#ifndef LOG_LEVEL
#define LOG_LEVEL LOG_NONE

View File

@ -12,30 +12,14 @@
#define _STACK_H_
#include "unicstl_internal.h"
struct _stack_node
{
void * obj;
struct _stack_node * next;
};
#include "deque.h"
struct _stack
{
// -------------------- private --------------------
/**
* @brief head pointer of stack
* 1. linklist: head->next is valid, head->obj is NULL
* 2. array: head->obj is valid, head->next is NULL,
*/
struct _stack_node * _head;
size_t _size;
size_t _obj_size;
size_t _capacity;
size_t _ratio;
deque_t _deque;
iterator_t _iter_deque;
struct _iterator _iter;
void (*_destory)(struct _stack* self);
// -------------------- public --------------------
@ -60,9 +44,9 @@ struct _stack
typedef struct _stack* stack_t;
// create and free stack
stack_t stack_new(size_t obj_size);
stack_t stack_new2(size_t obj_size, size_t capacity);
void stack_free(stack_t* stack);
#define stack_new(obj_type) stack_new2(sizeof(obj_type), 16)
#endif // _STACK_H_

View File

@ -10,6 +10,8 @@
*/
#ifndef _UNICSTL_CONFIG_H_
// #define NDEBUG // release
/**
* @brief unicstl contains which module
*
@ -28,17 +30,17 @@
*
*/
#define UNICSTL_MALLOC
#define UNICSTL_ASSERT
/**
* @brief
*
*/
#ifndef NDEBUG
#define UNICSTL_DEBUG
#endif
#ifdef UNICSTL_DEBUG
#define UNICSTL_DEBUG_STACK
#define UNICSTL_DEBUG_QUEUE
#define UNICSTL_DEBUG_DEQUE
@ -47,10 +49,8 @@
#define UNICSTL_DEBUG_GRAPH
/**
* @brief log enable
*/
// #define LOGGER_ON
#define UNICSTL_ASSERT // assert
#define LOGGER_ON // logger on
/**
* @brief debug level
@ -59,7 +59,8 @@
* 2. WARN
* 3. ERROR
*/
#define LOG_LEVEL 4
#define LOG_LEVEL 0
/**
* @brief
* 0. simple

View File

@ -51,7 +51,7 @@ static inline void _unicstl_assert(const char *expr, const char *file, int line)
exit(1);
}
#else
#define unicstl_assert assert
#define unicstl_assert(expr) // assert(expr)
#endif

View File

@ -66,6 +66,13 @@ static size_t deque_size(struct _deque* self)
return self->ringbuf->size(self->ringbuf);
}
static size_t deque_capacity(struct _deque* self)
{
unicstl_assert(self != NULL);
unicstl_assert(self->ringbuf != NULL);
return self->ringbuf->capacity(self->ringbuf);
}
static bool deque_empty(struct _deque* self)
{
unicstl_assert(self != NULL);

View File

@ -10,247 +10,84 @@
*/
#include "stack.h"
static struct _stack_node* stack_node_new(void *obj, size_t obj_size)
{
void* new_obj = (void*)calloc(1, obj_size);
if (new_obj == NULL)
{
goto done;
}
memmove(new_obj, obj, obj_size);
struct _stack_node* new_node = (struct _stack_node*)malloc(sizeof(struct _stack_node));
if (new_node == NULL)
{
goto done1;
}
new_node->obj = new_obj;
new_node->next = NULL;
return new_node;
done1:
free(new_obj);
done:
return NULL;
}
static void stack_node_free(struct _stack_node** node)
{
if(node != NULL && *node != NULL)
{
if((*node)->obj != NULL)
{
free((*node)->obj);
}
free(*node);
*node = NULL;
}
}
static bool stack_push(struct _stack* self, void* obj)
{
unicstl_assert(self != NULL);
unicstl_assert(self->_head != NULL);
unicstl_assert(obj != NULL);
unicstl_assert(self->_deque != NULL);
deque_t deque = self->_deque;
struct _stack_node* new_node = stack_node_new(obj, self->_obj_size);
if (new_node == NULL)
{
return false;
}
new_node->next = self->_head->next;
self->_head->next = new_node;
self->_size += 1;
return true;
return deque->push_back(deque, obj);
}
static bool stack_pop(struct _stack* self, void* obj)
{
unicstl_assert(self != NULL);
unicstl_assert(self->_head != NULL);
if (self->empty(self))
{
return false;
}
struct _stack_node* node = self->_head->next;
unicstl_assert(self->_deque != NULL);
deque_t deque = self->_deque;
if (obj != NULL)
{
memmove(obj, node->obj, self->_obj_size);
}
self->_head->next = node->next;
stack_node_free(&node);
self->_size -= 1;
return true;
return deque->pop_back(deque, obj);
}
static bool stack_peek(struct _stack* self, void* obj)
{
unicstl_assert(self != NULL);
unicstl_assert(self->_head != NULL);
unicstl_assert(obj != NULL);
unicstl_assert(self->_deque != NULL);
deque_t deque = self->_deque;
if (self->empty(self))
{
return false;
}
struct _stack_node * node = self->_head->next;
memmove(obj, node->obj, self->_obj_size);
return true;
return deque->back(deque, obj);
}
static size_t stack_size(struct _stack* self)
{
unicstl_assert(self != NULL);
return self->_size;
unicstl_assert(self->_deque != NULL);
deque_t deque = self->_deque;
return deque->size(deque);
}
static bool stack_empty(struct _stack* self)
{
unicstl_assert(self != NULL);
unicstl_assert(self->size != NULL);
return self->size(self) == 0;
unicstl_assert(self->_deque != NULL);
deque_t deque = self->_deque;
return deque->empty(deque);
}
static size_t stack_capacity(struct _stack* self)
{
unicstl_assert(self != NULL);
return self->_capacity;
unicstl_assert(self->_deque != NULL);
deque_t deque = self->_deque;
return deque->capacity(deque);
}
static bool stack_clear(struct _stack* self)
{
unicstl_assert(self != NULL);
if (self->empty(self))
{
return true;
}
unicstl_assert(self->_deque != NULL);
deque_t deque = self->_deque;
struct _stack_node* node = self->_head->next;
while (node != NULL)
{
self->_head->next = node->next;
stack_node_free(&node);
node = self->_head->next;
}
self->_size = 0;
return true;
return deque->clear(deque);
}
static void stack_destory(struct _stack* self)
{
unicstl_assert(self != NULL);
self->clear(self);
if(self->_head != NULL)
{
free(self->_head);
self->_head = NULL;
}
unicstl_assert(self->_deque != NULL);
deque_free(&self->_deque);
}
static void stack_print(struct _stack* self)
{
size_t i = 0;
struct _stack_node* node = self->_head->next;
while (node != NULL)
{
self->print_obj(node->obj);
node = node->next;
}
}
static bool stack2_push(struct _stack* self, void* obj)
{
unicstl_assert(self != NULL);
unicstl_assert(self->_head != NULL);
unicstl_assert(obj != NULL);
unicstl_assert(self->_deque != NULL);
deque_t deque = self->_deque;
deque->print_obj = self->print_obj;
if (self->size(self) == self->capacity(self))
{
void* obj_new = (void*)realloc(self->_head->obj, self->capacity(self) * self->_obj_size * self->_ratio);
if (obj_new == NULL)
{
return false;
}
self->_head->obj = obj_new;
}
size_t top = self->size(self);
size_t offset = top * self->_obj_size;
memmove((char*)self->_head->obj + offset, obj, self->_obj_size);
self->_size += 1;
return true;
}
static bool stack2_pop(struct _stack* self, void* obj)
{
unicstl_assert(self != NULL);
unicstl_assert(self->_head != NULL);
if (self->empty(self))
{
return false;
}
if (obj != NULL)
{
size_t top = self->size(self) - 1;
size_t offset = top * self->_obj_size;
memmove(obj, (char*)self->_head->obj + offset, self->_obj_size);
}
self->_size -= 1;
return true;
}
static bool stack2_peek(struct _stack* self, void* obj)
{
unicstl_assert(self != NULL);
unicstl_assert(self->_head != NULL);
unicstl_assert(obj != NULL);
if (self->empty(self))
{
return false;
}
size_t top = self->size(self) - 1;
size_t offset = top * self->_obj_size;
memmove(obj, (char *)self->_head->obj + offset, self->_obj_size);
return true;
}
static void stack2_destory(struct _stack* self)
{
unicstl_assert(self != NULL);
self->clear(self);
if(self->_head != NULL)
{
if(self->_head->obj != NULL)
{
free(self->_head->obj);
self->_head->obj = NULL;
}
free(self->_head);
self->_head = NULL;
}
}
static void stack2_print(struct _stack* self)
{
unicstl_assert(self != NULL);
unicstl_assert(self->_head != NULL);
void* obj = NULL;
size_t offset = 0;
for (int i = self->size(self) - 1; i >= 0; i--)
{
offset = self->_obj_size * i;
obj = (char*)self->_head->obj + offset;
self->print_obj(obj);
}
deque->print(deque);
}
bool stack_iter_hasnext(struct _iterator* iter)
@ -259,11 +96,7 @@ bool stack_iter_hasnext(struct _iterator* iter)
unicstl_assert(iter->_container != NULL);
stack_t self = (stack_t)iter->_container;
if(iter->_index < self->size(self))
{
return true;
}
return false;
return self->_iter_deque->hasnext(self->_iter_deque);
}
/**
@ -276,65 +109,42 @@ const void* stack_iter_next(struct _iterator* iter)
unicstl_assert(iter->_container != NULL);
stack_t self = (stack_t)iter->_container;
void *obj = NULL;
if(self->_head->obj == NULL)
{
// base on linklist
struct _stack_node* node = (struct _stack_node *)iter->_node;
if(node != NULL)
{
obj = node->obj;
iter->_node = node->next;
}
}
else
{
// base on array
size_t index = self->size(self) - 1 - iter->_index;
obj = self->_head->obj + self->_obj_size * index;
}
iter->_index += 1;
return obj;
return self->_iter_deque->next(self->_iter_deque);
}
iterator_t stack_iter(struct _stack* self)
{
unicstl_assert(self != NULL);
iterator_t iter = &self->_iter;
unicstl_assert(self->_deque != NULL);
deque_t deque = self->_deque;
iterator_t iter = &self->_iter;
iter->_container = self;
iter->_index = 0;
iter->_node = self->_head->next;
self->_iter_deque = deque->iter(deque, DEQUE_FORWARD);
iter->hasnext = stack_iter_hasnext;
iter->next = stack_iter_next;
return iter;
}
static bool stack_init(struct _stack* self, size_t obj_size)
static bool stack_init(struct _stack* self, size_t obj_size, size_t capacity)
{
// unicstl_assert(self != NULL);
// unicstl_assert(obj_size != 0);
if(self == NULL || obj_size == 0)
if(self == NULL || obj_size == 0 || capacity == 0)
{
return false;
}
// -------------------- private --------------------
self->_obj_size = obj_size;
self->_size = 0;
self->_capacity = UINT32_MAX;
self->_ratio = 1;
self->_head = (struct _stack_node *)malloc(sizeof(struct _stack_node));
if (self->_head == NULL)
self->_deque = deque_new(obj_size, capacity);
if(self->_deque == NULL)
{
return false;
}
self->_head->obj = NULL;
self->_head->next = NULL;
self->_iter.next = stack_iter_next;
self->_iter.hasnext = stack_iter_hasnext;
self->_destory = stack_destory;
@ -352,91 +162,16 @@ static bool stack_init(struct _stack* self, size_t obj_size)
// iter
self->iter = stack_iter;
// -------------------- default --------------------
self->print_obj = default_print_obj;
// -------------------- debug --------------------
self->print = stack_print;
return true;
}
static bool stack_init2(struct _stack* self, size_t obj_size, size_t capacity)
{
// unicstl_assert(self != NULL);
if(self == NULL || obj_size == 0 || capacity == 0)
{
return false;
}
// -------------------- private --------------------
self->_obj_size = obj_size;
self->_size = 0;
self->_capacity = capacity;
self->_ratio = 2;
self->_head = (struct _stack_node*)malloc(sizeof(struct _stack_node));
if (self->_head == NULL)
{
return false;
}
self->_head->next = NULL;
self->_head->obj = (void *)calloc(self->_capacity, self->_obj_size);
if (self->_head->obj == NULL)
{
free(self->_head);
self->_head = NULL;
return false;
}
self->_iter.next = stack_iter_next;
self->_iter.hasnext = stack_iter_hasnext;
self->_destory = stack2_destory;
// -------------------- public --------------------
// kernel
self->push = stack2_push;
self->pop = stack2_pop;
self->peek = stack2_peek;
self->empty = stack_empty;
// base
self->size = stack_size;
self->capacity = stack_capacity;
self->clear = stack_clear;
// iter
self->iter = stack_iter;
// -------------------- default --------------------
self->print_obj = default_print_obj;
// -------------------- debug --------------------
self->print = stack2_print;
return true;
}
stack_t stack_new(size_t obj_size)
{
stack_t stack = NULL;
stack = (struct _stack*)calloc(1, sizeof(struct _stack));
if(stack == NULL)
{
return NULL;
}
if(stack_init(stack, obj_size) != true)
{
free(stack);
return NULL;
}
return stack;
}
stack_t stack_new2(size_t obj_size, size_t capacity)
{
stack_t stack = NULL;
@ -446,7 +181,7 @@ stack_t stack_new2(size_t obj_size, size_t capacity)
return NULL;
}
if(stack_init2(stack, obj_size, capacity) != true)
if(stack_init(stack, obj_size, capacity) != true)
{
free(stack);
return NULL;
@ -456,7 +191,6 @@ stack_t stack_new2(size_t obj_size, size_t capacity)
void stack_free(stack_t *stack)
{
unicstl_assert(stack != NULL);
if(stack != NULL && *stack != NULL)
{
if((*stack)->_destory != NULL)

View File

@ -25,19 +25,19 @@ void default_print_obj(const void* obj)
size_t unicstl_new_capacity(size_t capacity)
{
size_t new_capacity = 0;
if(capacity < 4)
if(capacity <= 8)
{
new_capacity = 8;
new_capacity = 16;
}
else if (capacity < 1024)
{
new_capacity = capacity * 2;
// capacity * 2;
new_capacity = capacity << 1;
}
else
{
// capacity + capacity / 8 = capacity * 1.125;
new_capacity = capacity + (capacity >> 3);
}
return new_capacity;
}

View File

@ -221,7 +221,7 @@ static void test_stack_clear(void)
static void test_stack_num(void)
{
size_t i = 0;
int data[] = { 1,2,3,4,5,6,7,8,9,10 };
int data[10] = { 1,2,3,4,5,6,7,8,9,10 };
int temp = 0;
size_t len = sizeof(data) / sizeof(data[0]);
@ -237,7 +237,15 @@ static void test_stack_num(void)
TEST_ASSERT_TRUE(stack->push(stack, &data[i]));
TEST_ASSERT_EQUAL_INT(i + 1, stack->size(stack));
LOG_DEBUG("[%d] stack size: %d", i, stack->size(stack));
stack->print(stack);
TEST_ASSERT_TRUE(stack->peek(stack, &temp));
for(int j = 0; j < 10; j++)
{
printf("%d ", data[j]);
}
LOG_DEBUG("data[%d]=%d, temp=%d\n", i, data[i], temp);
TEST_ASSERT_EQUAL_INT(data[i], temp);
}