Files

82 lines
2.5 KiB
C
Raw Permalink Normal View History

2026-08-10 01:21:15 +08:00
#include <c_ArrayList.h>
#include <c_Memory.h>
#define DEFAULT_INITIAL_CAPACITY 4
/* ------------------------------------------------------------------------------------------------------------------ */
/* */
c_err_t c_ArrayList_Init(c_ArrayList_t* self, c_size_t obj_size, c_size_t capacity) {
if (!self || obj_size == 0) return C_ERR_PARAM;
self->obj_size = (int)obj_size;
self->capacity = (capacity > 0) ? capacity : DEFAULT_INITIAL_CAPACITY;
self->size = 0;
// 分配連續記憶體空間:容量 * 單個物件大小
self->array = C_ALLOC(self->capacity * self->obj_size);
if (!self->array) {
self->capacity = 0;
return C_ERR_NOMEM;
}
return C_ERR_SUCCESS;
}
void c_ArrayList_Destroy(c_ArrayList_t* self) {
if (!self) return;
C_FREE(self->array);
self->capacity = 0;
self->size = 0;
self->obj_size=0;
}
c_err_t c_ArrayList_Add(c_ArrayList_t* self, void* obj) {
if (!self || !self->array || !obj) return C_ERR_PARAM;
// 動態擴容邏輯
if (self->size >= self->capacity) {
const c_size_t new_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_addr = (char*)self->array + (self->size * self->obj_size);
memcpy(target_addr, obj, self->obj_size);
self->size++;
return C_ERR_SUCCESS;
}
void* c_ArrayList_Get(c_ArrayList_t* self, c_size_t index) {
if (!self || !self->array || index >= self->size) {
return NULL;
}
// 回傳內部記憶體塊中該元素的實際起始地址
return (char*)self->array + (index * self->obj_size);
}
c_err_t c_ArrayList_Remove(c_ArrayList_t* self, c_size_t index) {
if (!self || !self->array) return C_ERR_PARAM;
if (index >= self->size) return C_ERR_INDEX;
// 如果刪除的不是最後一個元素,需要將後方所有物件往前平移一個單位
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 處理重疊記憶體區塊的複製
memmove(dest, src, num_elements_to_move * self->obj_size);
}
self->size--;
return C_ERR_SUCCESS;
}