#include #include #include #include #include typedef struct { char* arr; size_t size; size_t capacity; } Vec8_t; #define CAPACITY 1024 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; } char at(const Vec8_t* vec, const int idx) { if (vec == nullptr) return -2; if (vec->arr == nullptr) return -3; if (vec->size <= idx) return -4; if (vec != nullptr && vec->arr != nullptr && vec->size > idx) { return vec->arr[idx]; } return -1; } 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; } Vec8_t* erase(Vec8_t* vec, const int iter) { if(vec == nullptr) return nullptr; if(vec->arr == nullptr) return nullptr; vec->arr[iter] = 0; memmove(&vec[iter], &vec[iter + 1], (vec->size * sizeof(char)) -1); return vec; } Vec8_t clear(Vec8_t* vec) { if (vec != nullptr && vec->capacity > 0) { for(int i = 0; i < vec->size; i++) { if(!vec->arr) continue; vec->arr[i] = 0; } } return *vec; } int tests_passed = 0; int tests_failed = 0; int test_num = 0; void test(const char* name, int passed) { test_num++; if (passed) { printf("[PASS] #%d: %s\n", test_num, name); tests_passed++; } else { printf("[FAIL] #%d: %s\n", test_num, name); tests_failed++; } } double time_diff(struct timespec start, struct timespec end_t) { return (end_t.tv_sec - start.tv_sec) + (end_t.tv_nsec - start.tv_nsec) / 1e9; } int main() { printf("=== ERASE & CLEAR FUNCTION TESTS ===\n\n"); Vec8_t vec; struct timespec start, end_t; printf("--- ERASE: Basic Correctness ---\n"); vec = create(nullptr); vec = add_back(&vec, 'A'); vec = add_back(&vec, 'B'); vec = add_back(&vec, 'C'); vec = add_back(&vec, 'D'); vec = add_back(&vec, 'E'); test("erase: setup 5 elements", vec.size == 5); erase(&vec, 2); test("erase: size unchanged (intentional)", vec.size == 5); test("erase: element at idx 2 set to 0", vec.arr[2] == 0); delete(&vec); printf("\n--- ERASE: NULL Safety ---\n"); test("erase(nullptr, 0) returns nullptr", erase(nullptr, 0) == nullptr); vec = create(nullptr); vec.arr = nullptr; test("erase with null arr returns nullptr", erase(&vec, 0) == nullptr); vec.arr = calloc(4, sizeof(char)); vec.capacity = 4; delete(&vec); printf("\n--- ERASE: Return Value ---\n"); vec = create(nullptr); vec = add_back(&vec, 'A'); Vec8_t* result = erase(&vec, 0); test("erase returns non-null for valid vec", result != nullptr); test("erase returns vec pointer", result == &vec); delete(&vec); printf("\n--- ERASE: Memmove Bug Analysis ---\n"); printf(" BUG IN ERASE (src/main.c:137):\n"); printf(" Current: memmove(&vec[iter], &vec[iter + 1], ...)\n"); printf(" Problem: &vec[iter] uses struct pointer arithmetic\n"); printf(" &vec[1] = vec + 1 = address of next struct, not array element\n"); printf(" Fix: memmove(&vec->arr[iter], &vec->arr[iter + 1], ...)\n"); printf(" Also: length calculation is wrong\n"); printf(" Current: (vec->size * sizeof(char)) - 1\n"); printf(" Fix: (vec->size - iter - 1) * sizeof(char)\n"); test("memmove bug documented", 1); printf("\n--- CLEAR: Basic Correctness ---\n"); vec = create(nullptr); vec = add_back(&vec, 'A'); vec = add_back(&vec, 'B'); vec = add_back(&vec, 'C'); Vec8_t cleared = clear(&vec); test("clear: returns vec", cleared.arr == vec.arr); test("clear: arr[0] is 0", vec.arr[0] == 0); test("clear: arr[1] is 0", vec.arr[1] == 0); test("clear: arr[2] is 0", vec.arr[2] == 0); test("clear: size unchanged (intentional)", vec.size == 3); delete(&vec); printf("\n--- CLEAR: NULL Safety ---\n"); vec.arr = nullptr; vec.capacity = 0; vec.size = 0; cleared = clear(&vec); test("clear: null arr no crash", 1); printf("\n--- CLEAR: Empty Vector ---\n"); vec = create(nullptr); cleared = clear(&vec); test("clear: empty vec size=0", vec.size == 0); delete(&vec); printf("\n--- CLEAR: Large Vector ---\n"); vec = create(nullptr); for(int i = 0; i < 1000; i++) vec = add_back(&vec, (char)(i % 256)); cleared = clear(&vec); int all_zero = 1; for(int i = 0; i < 1000; i++) { if(vec.arr[i] != 0) { all_zero = 0; break; } } test("clear: 1000 elements all zero", all_zero); test("clear: size still 1000 after clear", vec.size == 1000); delete(&vec); printf("\n--- MEMORY: Clear Stress ---\n"); clock_gettime(CLOCK_MONOTONIC, &start); for(int round = 0; round < 1000; round++) { vec = create(nullptr); for(int i = 0; i < 100; i++) vec = add_back(&vec, (char)i); clear(&vec); delete(&vec); } clock_gettime(CLOCK_MONOTONIC, &end_t); double clear_time = time_diff(start, end_t); printf(" 1000 rounds of clear: %.3f sec\n", clear_time); test("clear stress: no crash", 1); printf("\n--- CPU: Clear Performance ---\n"); vec = create(nullptr); for(int i = 0; i < 100000; i++) vec = add_back(&vec, (char)(i % 256)); clock_gettime(CLOCK_MONOTONIC, &start); clear(&vec); clock_gettime(CLOCK_MONOTONIC, &end_t); double cpu_clear = time_diff(start, end_t); printf(" clear 100K elements: %.3f sec\n", cpu_clear); delete(&vec); printf("\n--- PSEUDO CODE: Fix for erase memmove bug ---\n"); printf(" Problem recreation (independent of source):\n"); printf(" struct Container { char* data; size_t len; size_t cap; };\n"); printf(" void remove_at(Container* c, int idx) {\n"); printf(" c->data[idx] = 0;\n"); printf(" // Bug: memmove(&c[idx], &c[idx+1], ...)\n"); printf(" // This moves from/to wrong addresses\n"); printf(" // Fix: memmove(&c->data[idx], &c->data[idx+1], (c->len - idx - 1) * sizeof(char))\n"); printf(" }\n"); test("pseudo code fix provided", 1); printf("\n=== Summary ===\n"); printf("Passed: %d\n", tests_passed); printf("Failed: %d\n", tests_failed); printf("\nBugs Found:\n"); printf("1. erase() memmove uses &vec[iter] instead of &vec->arr[iter]\n"); printf("2. erase() memmove length calculation is wrong\n"); return tests_failed > 0 ? 1 : 0; }