#include #include #include #include #define CAPACITY 1024 #define nullptr ((void*)0) typedef struct { char* arr; size_t size; size_t capacity; } Vec8_t; Vec8_t create(const Vec8_t* input) { Vec8_t vec = { .arr = nullptr, .size = 0, .capacity = CAPACITY }; if (input != nullptr && input->size > 0) vec.size = input->size + 1; vec.arr = calloc(vec.capacity, sizeof(char)); return vec; } void delete(Vec8_t* vec) { if (vec->arr != nullptr) { free(vec->arr); vec->arr = nullptr; } } Vec8_t add_back(Vec8_t* vec, const char val) { if (vec->size >= vec->capacity) { vec->capacity *= 2; char* nvec = reallocf(vec->arr, vec->capacity * sizeof(char)); if (nvec == NULL) return *vec; vec->arr = nvec; } vec->arr[vec->size] = val; vec->size++; return *vec; } // Exact copy of src/main.c single erase (lines 128-137) __attribute__((overloadable)) Vec8_t* erase(Vec8_t* vec, const int iter) { if(vec == nullptr) return nullptr; if(vec->arr == nullptr) return nullptr; if(iter >= vec->size) return nullptr; memmove(&vec->arr[iter], &vec->arr[iter + 1], (vec->size - iter - 1) * sizeof(char)); vec->arr[vec->size - 1] = 0; vec->size--; return vec; } // Exact copy of src/main.c range erase (lines 139-151) __attribute__((overloadable)) Vec8_t* erase(Vec8_t* vec, const int iter_start, const int iter_end) { if(vec == nullptr) return nullptr; if(vec->arr == nullptr) return nullptr; if(iter_start < 0 || iter_end > vec->size) return nullptr; int diff = iter_end - iter_start; memmove(&vec->arr[iter_start], &vec->arr[iter_end], (vec->size - iter_end) * sizeof(char)); for(size_t i = vec->size; i > iter_end; i--) { vec->arr[i] = 0; // BUG: i starts at vec->size (out of bounds!) } vec->size -= diff; return vec; } void test_single_erase() { printf("=== Testing Single Erase ===\n"); Vec8_t vec = create(nullptr); for (int i = 0; i < 10; i++) add_back(&vec, 'a' + i); printf("Before: "); for (int i = 0; i < vec.size; i++) printf("%c ", vec.arr[i]); printf("(size=%zu)\n", vec.size); erase(&vec, 2); // Erase 'c' printf("After erase(2): "); for (int i = 0; i < vec.size; i++) printf("%c ", vec.arr[i]); printf("(size=%zu)\n", vec.size); assert(vec.size == 9); assert(vec.arr[0] == 'a'); assert(vec.arr[1] == 'b'); assert(vec.arr[2] == 'd'); // Shifted left correctly printf("Single erase: PASS\n\n"); delete(&vec); } void test_single_erase_large() { printf("=== Testing Single Erase (100k elements) ===\n"); Vec8_t vec = create(nullptr); for (int i = 0; i < 100000; i++) add_back(&vec, (char)(i % 256)); erase(&vec, 0); // Erase front assert(vec.size == 99999); assert(vec.arr[0] == 1); erase(&vec, 50000); // Erase middle assert(vec.size == 99998); assert(vec.arr[50000] == 2); // Shifted correctly printf("Large single erase: PASS\n\n"); delete(&vec); } void test_range_erase() { printf("=== Testing Range Erase (exclusive end) ===\n"); Vec8_t vec = create(nullptr); for (int i = 0; i < 10; i++) add_back(&vec, 'a' + i); printf("Before: "); for (int i = 0; i < vec.size; i++) printf("%c ", vec.arr[i]); printf("(size=%zu)\n", vec.size); erase(&vec, 2, 4); // Erase [2,4) -> indices 2,3 ('c','d') printf("After erase(2,4): "); for (int i = 0; i < vec.size; i++) printf("%c ", vec.arr[i]); printf("(size=%zu)\n", vec.size); // Expected: a b e f g h i j (size=8) assert(vec.size == 8); assert(vec.arr[0] == 'a'); assert(vec.arr[1] == 'b'); assert(vec.arr[2] == 'e'); // Shifted correctly // Check zeroing bug (zeros wrong positions due to out-of-bounds access) printf("Raw array: "); for (int i = 0; i < 10; i++) printf("%c", vec.arr[i] == 0 ? '0' : vec.arr[i]); printf("\n"); printf("Range erase: PASS (but zeroing loop has out-of-bounds bug)\n\n"); delete(&vec); } void test_range_erase_to_end() { printf("=== Testing Range Erase to End ===\n"); Vec8_t vec = create(nullptr); for (int i = 0; i < 10; i++) add_back(&vec, 'a' + i); Vec8_t* res = erase(&vec, 2, 10); // Erase [2,10) -> indices 2-9 assert(res != nullptr); assert(vec.size == 2); assert(vec.arr[0] == 'a'); assert(vec.arr[1] == 'b'); printf("Erase to end: PASS\n\n"); delete(&vec); } int main() { test_single_erase(); test_single_erase_large(); test_range_erase(); test_range_erase_to_end(); printf("All tests completed.\n"); return 0; }