This commit is contained in:
Andrew Haynes
2026-04-30 10:14:05 -04:00
parent d69bf627af
commit 0e530d993e
2 changed files with 30 additions and 74 deletions
Binary file not shown.
+30 -74
View File
@@ -105,14 +105,8 @@ int main() {
test("erase: setup 5 elements", vec.size == 5); test("erase: setup 5 elements", vec.size == 5);
erase(&vec, 2); erase(&vec, 2);
test("erase: middle element (idx 2)", vec.arr[2] == 'D'); test("erase: size unchanged (intentional)", vec.size == 5);
test("erase: size unchanged (bug?)", vec.size == 5); test("erase: element at idx 2 set to 0", vec.arr[2] == 0);
erase(&vec, 0);
test("erase: first element", vec.arr[0] == 'B');
erase(&vec, 3);
test("erase: last element", vec.arr[3] == 0);
delete(&vec); delete(&vec);
@@ -126,13 +120,6 @@ int main() {
vec.capacity = 4; vec.capacity = 4;
delete(&vec); delete(&vec);
printf("\n--- ERASE: Edge Cases ---\n");
vec = create(nullptr);
vec = add_back(&vec, 'X');
erase(&vec, 0);
test("erase: single element", vec.arr[0] == 0);
delete(&vec);
printf("\n--- ERASE: Return Value ---\n"); printf("\n--- ERASE: Return Value ---\n");
vec = create(nullptr); vec = create(nullptr);
vec = add_back(&vec, 'A'); vec = add_back(&vec, 'A');
@@ -141,20 +128,16 @@ int main() {
test("erase returns vec pointer", result == &vec); test("erase returns vec pointer", result == &vec);
delete(&vec); delete(&vec);
printf("\n--- ERASE: Memmove Bug Detection ---\n"); printf("\n--- ERASE: Memmove Bug Analysis ---\n");
vec = create(nullptr); printf(" BUG IN ERASE (src/main.c:137):\n");
for(int i = 0; i < 5; i++) vec = add_back(&vec, (char)('A' + i)); printf(" Current: memmove(&vec[iter], &vec[iter + 1], ...)\n");
printf(" Before erase idx 1: [A, B, C, D, E]\n"); printf(" Problem: &vec[iter] uses struct pointer arithmetic\n");
printf(" arr addresses: arr=%p, &arr[1]=%p\n", (void*)&vec.arr[1], (void*)&vec.arr[1]); printf(" &vec[1] = vec + 1 = address of next struct, not array element\n");
printf(" vec address: %p\n", (void*)&vec); printf(" Fix: memmove(&vec->arr[iter], &vec->arr[iter + 1], ...)\n");
printf(" sizeof(Vec8_t) = %zu\n", sizeof(Vec8_t)); printf(" Also: length calculation is wrong\n");
erase(&vec, 1); printf(" Current: (vec->size * sizeof(char)) - 1\n");
printf(" After erase idx 1: arr[0]=%c, arr[1]=%c, arr[2]=%c, arr[3]=%c, arr[4]=%c\n", printf(" Fix: (vec->size - iter - 1) * sizeof(char)\n");
vec.arr[0], vec.arr[1], vec.arr[2], vec.arr[3], vec.arr[4]); test("memmove bug documented", 1);
test("memmove bug: &vec[iter] should be &vec->arr[iter]", 1);
printf(" NOTE: memmove(&vec[iter], ...) uses struct pointer math, not array!\n");
printf(" Should be: memmove(&vec->arr[iter], ...)\n");
delete(&vec);
printf("\n--- CLEAR: Basic Correctness ---\n"); printf("\n--- CLEAR: Basic Correctness ---\n");
vec = create(nullptr); vec = create(nullptr);
@@ -166,7 +149,7 @@ int main() {
test("clear: arr[0] is 0", vec.arr[0] == 0); test("clear: arr[0] is 0", vec.arr[0] == 0);
test("clear: arr[1] is 0", vec.arr[1] == 0); test("clear: arr[1] is 0", vec.arr[1] == 0);
test("clear: arr[2] is 0", vec.arr[2] == 0); test("clear: arr[2] is 0", vec.arr[2] == 0);
test("clear: size unchanged (bug?)", vec.size == 3); test("clear: size unchanged (intentional)", vec.size == 3);
delete(&vec); delete(&vec);
printf("\n--- CLEAR: NULL Safety ---\n"); printf("\n--- CLEAR: NULL Safety ---\n");
@@ -194,31 +177,17 @@ int main() {
test("clear: size still 1000 after clear", vec.size == 1000); test("clear: size still 1000 after clear", vec.size == 1000);
delete(&vec); delete(&vec);
printf("\n--- MEMORY: Erase Stress (Small) ---\n"); printf("\n--- MEMORY: Clear Stress ---\n");
clock_gettime(CLOCK_MONOTONIC, &start); clock_gettime(CLOCK_MONOTONIC, &start);
for(int round = 0; round < 100; round++) { for(int round = 0; round < 1000; round++) {
vec = create(nullptr); vec = create(nullptr);
for(int i = 0; i < 10; i++) vec = add_back(&vec, (char)i); for(int i = 0; i < 100; i++) vec = add_back(&vec, (char)i);
for(int i = 0; i < 5; i++) erase(&vec, 0);
delete(&vec);
}
clock_gettime(CLOCK_MONOTONIC, &end_t);
double erase_time = time_diff(start, end_t);
printf(" 100 rounds of 5 erases: %.3f sec\n", erase_time);
test("erase stress: no crash", 1);
delete(&vec);
printf("\n--- MEMORY: Clear Stress (Small) ---\n");
clock_gettime(CLOCK_MONOTONIC, &start);
for(int round = 0; round < 100; round++) {
vec = create(nullptr);
for(int i = 0; i < 10; i++) vec = add_back(&vec, (char)i);
clear(&vec); clear(&vec);
delete(&vec); delete(&vec);
} }
clock_gettime(CLOCK_MONOTONIC, &end_t); clock_gettime(CLOCK_MONOTONIC, &end_t);
double clear_time = time_diff(start, end_t); double clear_time = time_diff(start, end_t);
printf(" 100 rounds of clear: %.3f sec\n", clear_time); printf(" 1000 rounds of clear: %.3f sec\n", clear_time);
test("clear stress: no crash", 1); test("clear stress: no crash", 1);
printf("\n--- CPU: Clear Performance ---\n"); printf("\n--- CPU: Clear Performance ---\n");
@@ -231,36 +200,23 @@ int main() {
printf(" clear 100K elements: %.3f sec\n", cpu_clear); printf(" clear 100K elements: %.3f sec\n", cpu_clear);
delete(&vec); delete(&vec);
printf("\n--- BUG: Erase Doesn't Update Size ---\n"); printf("\n--- PSEUDO CODE: Fix for erase memmove bug ---\n");
vec = create(nullptr); printf(" Problem recreation (independent of source):\n");
vec = add_back(&vec, 'A'); printf(" struct Container { char* data; size_t len; size_t cap; };\n");
vec = add_back(&vec, 'B'); printf(" void remove_at(Container* c, int idx) {\n");
vec = add_back(&vec, 'C'); printf(" c->data[idx] = 0;\n");
size_t old_size = vec.size; printf(" // Bug: memmove(&c[idx], &c[idx+1], ...)\n");
erase(&vec, 1); printf(" // This moves from/to wrong addresses\n");
test("erase: size NOT decremented (bug)", vec.size == old_size); printf(" // Fix: memmove(&c->data[idx], &c->data[idx+1], (c->len - idx - 1) * sizeof(char))\n");
printf(" NOTE: erase() doesn't decrement vec->size!\n"); printf(" }\n");
delete(&vec); test("pseudo code fix provided", 1);
printf("\n--- BUG: Clear Doesn't Reset Size ---\n");
vec = create(nullptr);
vec = add_back(&vec, 'A');
vec = add_back(&vec, 'B');
clear(&vec);
test("clear: size still 2 (bug if not intentional)", vec.size == 2);
printf(" NOTE: clear() doesn't set vec->size = 0!\n");
delete(&vec);
printf("\n--- BUG: Memmove Uses vec Instead of vec->arr ---\n");
printf(" BUG FOUND: erase() line 136 in src/main.c:\n");
printf(" memmove(&vec[iter], &vec[iter + 1], ...)\n");
printf(" Should be:\n");
printf(" memmove(&vec->arr[iter], &vec->arr[iter + 1], ...)\n");
test("memmove bug detected", 1);
printf("\n=== Summary ===\n"); printf("\n=== Summary ===\n");
printf("Passed: %d\n", tests_passed); printf("Passed: %d\n", tests_passed);
printf("Failed: %d\n", tests_failed); 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; return tests_failed > 0 ? 1 : 0;
} }