#include #include c_err_t c_StringList_Init(c_StringList* list, c_size_t initial_capacity) { if (!list) return C_ERR_PARAM; list->size = 0; list->capacity = initial_capacity; if (initial_capacity > 0) { list->strings = (char**)C_ALLOC(initial_capacity * sizeof(char*)); if (!list->strings) { list->capacity = 0; return C_ERR_NOMEM; } } else { list->strings = NULL; } return C_ERR_OK; } void c_StringList_Destroy(c_StringList* list) { if (!list) return; if (list->strings) { for (c_size_t i = 0; i < list->size; i++) { C_FREE(list->strings[i]); } C_FREE(list->strings); } list->size = 0; list->capacity = 0; } c_err_t c_StringList_Append(c_StringList* list, const char* str) { if (!list || !str) return C_ERR_PARAM; if (list->size >= list->capacity) { c_size_t new_capacity = (list->capacity == 0) ? 4 : list->capacity * 2; char** new_array = (char**)C_REALLOC(list->strings, new_capacity * sizeof(char*)); if (!new_array) return C_ERR_NOMEM; list->strings = new_array; list->capacity = new_capacity; } char* copy = (char*)C_ALLOC(strlen(str) + 1); if (!copy) return C_ERR_NOMEM; strcpy(copy, str); list->strings[list->size++] = copy; return C_ERR_OK; } /** * Insert a new null-terminated string copy row at the very front of the collection list (Index 0) */ c_err_t c_StringList_Prepend(c_StringList* list, const char* str) { if (!list || !str) { return C_ERR_PARAM; } // 1. Dynamic scale check and array reallocation if capacity bounds are reached if (list->size >= list->capacity) { c_size_t new_capacity = (list->capacity == 0) ? 4 : list->capacity * 2; char** new_array = (char**)C_REALLOC(list->strings, new_capacity * sizeof(char*)); if (!new_array) { return C_ERR_NOMEM; } list->strings = new_array; list->capacity = new_capacity; } // 2. Allocate an isolated deep-copy heap buffer for the incoming string characters char* str_copy = (char*)C_ALLOC(strlen(str) + 1); if (!str_copy) { return C_ERR_NOMEM; } strcpy(str_copy, str); // 3. Shift all existing string pointer entries rightward by 1 to make room at index 0 for (c_size_t i = list->size; i > 0; i--) { list->strings[i] = list->strings[i - 1]; } // 4. Place the newly allocated string capsule at the front and increment tracking metrics list->strings[0] = str_copy; list->size++; return C_ERR_OK; } /** * Remove the first occurrence of a string value from the collection. * Cleans up memory allocations and tightly shifts elements to prevent layout leaks. */ c_err_t c_StringList_Remove(c_StringList* list, const char* str) { if (!list || !list->strings || !str) { return C_ERR_PARAM; } c_size_t target_idx = (c_size_t)-1; // 1. Linearly scan the string array to locate a matching value match for (c_size_t i = 0; i < list->size; i++) { if (list->strings[i] != NULL && strcmp(list->strings[i], str) == 0) { target_idx = i; break; } } // If the targeted string value does not exist, return an error code parameter if (target_idx == (c_size_t)-1) { return C_ERR_PARAM; } // 2. Safely free the individual string characters heap capsule C_FREE(list->strings[target_idx]); // Safe macro automatically sets index entry to NULL // 3. Shift subsequent array entries leftward to maintain dense cache prefetching locality for (c_size_t i = target_idx; i < list->size - 1; i++) { list->strings[i] = list->strings[i + 1]; } // 4. Update trailing metadata bounds list->size--; list->strings[list->size] = NULL; // Ensure the newly vacant tail slot is nullified safely return C_ERR_OK; }