#include #include #define DEFAULT_INIT_CAPACITY 4 c_err_t c_NlpStringList_Init(c_NlpStringList_t* list, c_size_t capacity) { if (!list ) return C_ERR_PARAM; list->count = 0; list->capacity = (capacity==0)?DEFAULT_INIT_CAPACITY:capacity; // Start small, grow exponentially list->items = (char**)C_ALLOC(sizeof(char*) * list->capacity); if (!list->items) return C_ERR_NOMEM; return C_ERR_OK; } void c_NlpStringList_Destroy(c_NlpStringList_t* list) { if (!list) return; if (list->items) { for (size_t i = 0; i < list->count; i++) { C_FREE(list->items[i]); } C_FREE(list->items); } list->count = 0; list->capacity = 0; } #include /** * @brief Appends a length-bounded string segment to the string list. * @param list Pointer to the active string list instance. * @param str Pointer to the source string segment. * @param str_length The length of characters to copy. * @return c_err_t C_ERR_OK on success, C_ERR_PARAM on invalid inputs, or C_ERR_NOMEM on allocation failure. */ c_err_t c_NlpStringList_Add(c_NlpStringList_t* list, const char* str, c_size_t str_length) { if (!list || !list->items || !str || str_length == 0) { return C_ERR_PARAM; } // 1. Double the internal storage capacity exponentially if the array bounds hit limits if (list->count >= list->capacity) { c_size_t new_capacity = list->capacity == 0 ? 4 : list->capacity * 2; char** new_items = (char**)C_ALLOC(sizeof(char*) * new_capacity); if (!new_items) return C_ERR_NOMEM; if (list->items && list->count > 0) { memcpy(new_items, list->items, sizeof(char*) * list->count); } C_FREE(list->items); list->items = new_items; list->capacity = new_capacity; } // 2. Allocate an isolated target heap layout tracking buffer segment (+1 for '\0') char* copy = (char*)C_ALLOC(str_length + 1); if (!copy) return C_ERR_NOMEM; // 3. Duplicate raw segment content and secure the terminal null byte memcpy(copy, str, str_length); copy[str_length] = '\0'; list->items[list->count++] = copy; return C_ERR_OK; } /** * @brief Appends a null-terminated string to the string list. * @param list Pointer to the active string list instance. * @param str Pointer to the null-terminated source string. * @return c_err_t C_ERR_OK on success, or parameter/ OOM error codes. */ c_err_t c_NlpStringList_AddStr(c_NlpStringList_t* list, const char* str) { if (!str) return C_ERR_PARAM; return c_NlpStringList_Add(list, str, strlen(str)); } c_err_t c_NlpStringList_Remove(c_NlpStringList_t* list, c_size_t index) { // 1. Guard against invalid instances and out-of-bound indices if (!list || index >= list->count) { return C_ERR_PARAM; } // 2. Safely free the dynamic string allocation to prevent memory leaks if (list->items[index] != NULL) { C_FREE(list->items[index]); } // 3. Shift subsequent string pointers left to fill the gap const c_size_t num_elements_to_shift = list->count - index - 1; if (num_elements_to_shift > 0) { memmove(&list->items[index], &list->items[index + 1], sizeof(char*) * num_elements_to_shift); } // 4. Decrement the structural item count list->count--; return C_ERR_OK; }