重构
This commit is contained in:
+77
-84
@@ -1,113 +1,106 @@
|
||||
#include "c_ArrayStack.h"
|
||||
#include <c_Memory.h>
|
||||
#include <c_ArrayStack.h>
|
||||
|
||||
#define DEFAULT_INITIAL_CAPACITY 4
|
||||
|
||||
c_err_t c_ArrayStack_Init(c_ArrayStack_t* self, int obj_size, c_size_t capacity) {
|
||||
if (!self || obj_size <= 0) return C_ERR_PARAM;
|
||||
c_err_t c_ArrayStack_Init(c_ArrayStack_t* self, c_size_t item_size, c_size_t capacity, c_Allocator_t* allocator) {
|
||||
if (!self || item_size == 0) return C_ERR_PARAM;
|
||||
|
||||
self->obj_size = (int)obj_size;
|
||||
self->allocator = (allocator != NULL) ? *allocator : c_DefaultAllocator;
|
||||
self->item_size = item_size;
|
||||
self->size = 0;
|
||||
self->capacity = capacity;
|
||||
self->capacity = (capacity > 0) ? capacity : DEFAULT_INITIAL_CAPACITY;
|
||||
|
||||
if (capacity==0) {
|
||||
// 为内部连续数据缓冲区分配内存
|
||||
self->array = c_Allocator_Alloc(&self->allocator, item_size * self->capacity);
|
||||
if (!self->array) return C_ERR_NOMEM;
|
||||
|
||||
return C_ERR_OK;
|
||||
}
|
||||
|
||||
void c_ArrayStack_Destroy(c_ArrayStack_t* self) {
|
||||
if (!self) return;
|
||||
if (self->array) {
|
||||
c_Allocator_Free(&self->allocator, self->array);
|
||||
self->array = NULL;
|
||||
}else {
|
||||
self->array = C_ALLOC(self->capacity * self->obj_size);
|
||||
if (!self->array) {
|
||||
self->capacity = 0;
|
||||
return C_ERR_NOMEM;
|
||||
}
|
||||
self->size = 0;
|
||||
self->capacity = 0;
|
||||
}
|
||||
|
||||
c_err_t c_ArrayStack_Resize(c_ArrayStack_t* self, c_size_t new_capacity) {
|
||||
if (!self) return C_ERR_PARAM;
|
||||
if (new_capacity == self->capacity) return C_ERR_OK;
|
||||
|
||||
// 情况 A: 如果新容量为 0,等同于彻底释放内存缓冲区
|
||||
if (new_capacity == 0) {
|
||||
if (self->array) {
|
||||
c_Allocator_Free(&self->allocator, self->array);
|
||||
self->array = NULL;
|
||||
}
|
||||
self->capacity = 0;
|
||||
self->size = 0;
|
||||
return C_ERR_OK;
|
||||
}
|
||||
|
||||
// 防御溢出检查
|
||||
if (new_capacity > (c_size_t)-1 / self->item_size) {
|
||||
return C_ERR_OUTOFBOUND;
|
||||
}
|
||||
|
||||
const c_size_t old_bytes = self->capacity * self->item_size;
|
||||
const c_size_t new_bytes = new_capacity * self->item_size;
|
||||
|
||||
// 直接调用闭环的 Realloc(内存管理器已自动处理了数据复制和老物理块释放)
|
||||
void* new_array = c_Allocator_Realloc(&self->allocator, self->array, old_bytes, new_bytes);
|
||||
if (!new_array) return C_ERR_NOMEM;
|
||||
|
||||
self->array = new_array;
|
||||
self->capacity = new_capacity;
|
||||
|
||||
// 缩容安全裁断:如果新容量调得比已有元素还小,强制截断到新容量边界
|
||||
if (self->size > new_capacity) {
|
||||
self->size = new_capacity;
|
||||
}
|
||||
|
||||
return C_ERR_OK;
|
||||
}
|
||||
|
||||
|
||||
void c_ArrayStack_Destroy(c_ArrayStack_t* self) {
|
||||
if (!self) return;
|
||||
|
||||
C_FREE(self->array);
|
||||
self->capacity = 0;
|
||||
self->size = 0;
|
||||
self->obj_size = 0;
|
||||
C_STATIC_FORCE_INLINE
|
||||
bool c_ArrayStack_EnsureCapacity(c_ArrayStack_t* self) {
|
||||
if (self->size < self->capacity) return true;
|
||||
c_size_t new_capacity = self->capacity * 2;
|
||||
if (new_capacity == 0) new_capacity = 4;
|
||||
return c_ArrayStack_Resize(self, new_capacity) == C_ERR_OK;
|
||||
}
|
||||
|
||||
c_err_t c_ArrayStack_Push(c_ArrayStack_t* self, void* obj) {
|
||||
if (!self || !self->array || !obj) return C_ERR_PARAM;
|
||||
c_err_t c_ArrayStack_Push(c_ArrayStack_t* self, const void* item) {
|
||||
if (!self || !item) return C_ERR_PARAM;
|
||||
if (!c_ArrayStack_EnsureCapacity(self)) return C_ERR_NOMEM;
|
||||
|
||||
if (self->size >= self->capacity) {
|
||||
const c_size_t new_capacity = (self->capacity==0)?DEFAULT_INITIAL_CAPACITY:(self->capacity<<1);
|
||||
void* new_array = C_REALLOC(self->array, new_capacity * self->obj_size);
|
||||
if (!new_array) {
|
||||
return C_ERR_NOMEM;
|
||||
}
|
||||
self->array = new_array;
|
||||
self->capacity = new_capacity;
|
||||
}
|
||||
|
||||
// 計算頂端目標記憶體地址並寫入資料
|
||||
char* target = (char*)self->array + (self->size * self->obj_size);
|
||||
memcpy(target, obj, self->obj_size);
|
||||
// 计算当前栈顶的物理指针坑位并直接拷贝进去
|
||||
char* target = (char*)self->array + (self->size * self->item_size);
|
||||
memcpy(target, item, self->item_size);
|
||||
self->size++;
|
||||
|
||||
return C_ERR_OK;
|
||||
}
|
||||
|
||||
c_err_t c_ArrayStack_Pop(c_ArrayStack_t* self, void* obj) {
|
||||
if (!self || !self->array || !obj) return C_ERR_PARAM;
|
||||
if (self->size == 0) return C_ERR_EMPTY; // 堆疊已空
|
||||
c_err_t c_ArrayStack_Pop(c_ArrayStack_t* self, void* out_item) {
|
||||
if (!self || self->size == 0) return C_ERR_OUTOFBOUND;
|
||||
|
||||
// 取得位於 size - 1 的堆疊頂端元素地址
|
||||
const char* pop_src = (char*)self->array + ((self->size - 1) * self->obj_size);
|
||||
|
||||
// 直接複製到呼叫端提供的記憶體中
|
||||
memcpy(obj, pop_src, self->obj_size);
|
||||
|
||||
self->size--;
|
||||
|
||||
if (self->size > 0 && self->size <= (self->capacity >> 2)) {
|
||||
c_size_t new_capacity = self->capacity >> 1;
|
||||
void* new_array = C_REALLOC(self->array, new_capacity * self->obj_size);
|
||||
if (new_array) {
|
||||
self->array = new_array;
|
||||
self->capacity = new_capacity;
|
||||
}
|
||||
self->size--; // 先缩减栈顶
|
||||
if (out_item) {
|
||||
// 找到被退栈的数据源并向外拷贝快照
|
||||
const char* source = (const char*)self->array + (self->size * self->item_size);
|
||||
memcpy(out_item, source, self->item_size);
|
||||
}
|
||||
|
||||
return C_ERR_OK;
|
||||
}
|
||||
|
||||
void* c_ArrayStack_Peek(c_ArrayStack_t* self) {
|
||||
if (!self || !self->array || self->size == 0) return NULL;
|
||||
return (char*)self->array + ((self->size - 1) * self->obj_size);
|
||||
void* c_ArrayStack_Peek(const c_ArrayStack_t* self) {
|
||||
if (!self || self->size == 0) return NULL;
|
||||
// 栈顶元素处于索引 size - 1 的坑位
|
||||
return (char*)self->array + ((self->size - 1) * self->item_size);
|
||||
}
|
||||
|
||||
c_err_t c_ArrayStack_Remove(c_ArrayStack_t* self, c_size_t index) {
|
||||
if (!self || !self->array) return C_ERR_PARAM;
|
||||
if (index >= self->size) return C_ERR_OUTOFBOUND;
|
||||
|
||||
// 如果刪除的不是頂端元素,則後續元素需向前平移一個單位
|
||||
if (index < self->size - 1) {
|
||||
char* dest = (char*)self->array + (index * self->obj_size);
|
||||
const char* src = dest + self->obj_size;
|
||||
const c_size_t num_elements_to_move = self->size - index - 1;
|
||||
memmove(dest, src, num_elements_to_move * self->obj_size);
|
||||
}
|
||||
|
||||
self->size--;
|
||||
|
||||
if (self->size > 0 && self->size <= (self->capacity >> 2)) {
|
||||
c_size_t new_capacity = self->capacity >> 1;
|
||||
void* new_array = C_REALLOC(self->array, new_capacity * self->obj_size);
|
||||
if (new_array) {
|
||||
self->array = new_array;
|
||||
self->capacity = new_capacity;
|
||||
}
|
||||
}
|
||||
|
||||
return C_ERR_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user