#include #include #include #include #include typedef struct { char* arr; size_t size; size_t capacity; } Vec8_t; Vec8_t create(const Vec8_t* input) { Vec8_t vec = { .arr = NULL, .size = 0, .capacity = 4 }; if (input == NULL) { vec.arr = calloc(vec.capacity, sizeof(char)); return vec; } if (input->size > 0) { vec.size = input->size + 1; } if (input->capacity >= vec.capacity) { vec.capacity = 2 * input->capacity; } vec.arr = calloc(vec.capacity, sizeof(char)); return vec; } void delete(Vec8_t* vec) { if (vec->arr != NULL) { free(vec->arr); } vec->arr = NULL; } Vec8_t add_back(Vec8_t* vec, const char val) { Vec8_t ret = { .arr = NULL, .capacity = 0, .size = 0 }; if (vec->size < vec->capacity) { vec->arr[vec->size] = val; vec->size++; return *vec; } if (vec->size >= vec->capacity) { Vec8_t nvec = create(vec); if (nvec.arr == NULL) { return *vec; } memcpy(&nvec.arr[0], &vec->arr[0], vec->size * sizeof(char)); if (nvec.arr && (nvec.size > 0 || nvec.size > vec->size)) { nvec.arr[vec->size] = val; } free(vec->arr); return nvec; } return ret; } 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; } void get_memory_usage(size_t* used, size_t* peak) { struct rusage ru; getrusage(RUSAGE_SELF, &ru); *used = ru.ru_maxrss * 1024; *peak = ru.ru_maxrss * 1024; } int main() { printf("=== FULL STRESS TEST: add_back only ===\n\n"); struct timespec start, end_t; Vec8_t vec; size_t max_elements = 0; int crashed = 0; printf("=== TEST 1: MAX ELEMENTS BEFORE CRASH ===\n\n"); vec = create(NULL); clock_gettime(CLOCK_MONOTONIC, &start); for (size_t i = 0; i < SIZE_MAX; i++) { vec = add_back(&vec, (char)(i % 256)); if (vec.arr == NULL) { max_elements = i; crashed = 1; break; } if (i % 100000000 == 0) { printf(" %zu elements: capacity %zu (%.2f GB)\n", i + 1, vec.capacity, (double)(vec.capacity * sizeof(char)) / 1024 / 1024 / 1024); } if (i >= 1000000000) { printf(" stopping at 1 billion elements\n"); max_elements = 1000000000; break; } } clock_gettime(CLOCK_MONOTONIC, &end_t); if (!crashed && vec.arr != NULL) { max_elements = vec.size; } printf("\nRESULT: %zu elements\n", max_elements); printf("capacity: %zu\n", vec.capacity); printf("memory: %.2f GB\n", (double)(vec.capacity * sizeof(char)) / 1024 / 1024 / 1024); printf("time: %.2f sec\n", time_diff(start, end_t)); delete(&vec); printf("\n=== TEST 2: DIRECT MALLOCATION LIMIT ===\n\n"); const size_t test_sizes[] = {1000000, 10000000, 100000000, 500000000, 1000000000}; int num_tests = 5; for (int t = 0; t < num_tests; t++) { size_t n = test_sizes[t]; printf("Testing %zu elements (%.2f GB)...\n", n, (double)(n * sizeof(char)) / 1024 / 1024 / 1024); char* test_arr = calloc(n, sizeof(char)); if (test_arr == NULL) { printf(" FAILED at %zu\n", n); break; } printf(" SUCCESS\n"); free(test_arr); } printf("\n=== TEST 3: SINGLE VECTOR ALLOCATION ===\n\n"); size_t single_max = 0; for (size_t n = 1000000; n <= 5000000000UL; n *= 2) { printf("Trying %.2f GB allocation...\n", (double)(n * sizeof(char)) / 1024 / 1024 / 1024); Vec8_t test_vec = create(NULL); Vec8_t* vp = calloc(1, sizeof(Vec8_t)); vp->arr = calloc(n, sizeof(char)); if (vp->arr == NULL) { printf(" FAILED at %.2f GB\n", (double)(n * sizeof(char)) / 1024 / 1024 / 1024); single_max = n / 2; free(vp); break; } printf(" SUCCESS: %.2f GB\n", (double)(n * sizeof(char)) / 1024 / 1024 / 1024); free(vp->arr); free(vp); delete(&test_vec); single_max = n; } printf("\n=== TEST 4: SPEED AT SCALE ===\n\n"); vec = create(NULL); clock_gettime(CLOCK_MONOTONIC, &start); for (size_t i = 0; i < 10000000; i++) { vec = add_back(&vec, (char)(i % 256)); } clock_gettime(CLOCK_MONOTONIC, &end_t); double t10m = time_diff(start, end_t); printf("10M elements:\n"); printf(" time: %.2f sec\n", t10m); printf(" rate: %.0f/sec\n", 10000000.0 / t10m); printf(" memory: %.2f MB\n", (vec.capacity * sizeof(char)) / 1024.0 / 1024.0); delete(&vec); printf("\n=== SUMMARY ===\n\n"); printf("Max elements (vector): %zu\n", max_elements); printf("Single allocation max: %zu (%.2f GB)\n", single_max, (double)(single_max * sizeof(char)) / 1024 / 1024 / 1024); return 0; }