a much more simplified version of push_back with reallocf instead of memcpy as it is faster (no copying just resizing the vector (entire point of vector))
This commit is contained in:
@@ -0,0 +1,108 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <mach/mach.h>
|
||||
#include <sys/resource.h>
|
||||
|
||||
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;
|
||||
}
|
||||
vec->size = 0;
|
||||
vec->capacity = 0;
|
||||
}
|
||||
|
||||
Vec8_t add_back(Vec8_t* vec, const char val) {
|
||||
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;
|
||||
}
|
||||
Vec8_t ret = { .arr = NULL, .capacity = 0, .size = 0 };
|
||||
return ret;
|
||||
}
|
||||
|
||||
vm_size_t get_physical_mem() {
|
||||
struct task_basic_info info;
|
||||
mach_msg_type_number_t count = TASK_BASIC_INFO_COUNT;
|
||||
task_info(mach_task_self(), TASK_BASIC_INFO, (task_info_t)&info, &count);
|
||||
return info.resident_size;
|
||||
}
|
||||
|
||||
int main() {
|
||||
printf("=== PHYSICAL MEMORY LEAK TEST ===\n\n");
|
||||
|
||||
printf("Initial physical: %.2f MB\n", get_physical_mem() / 1024.0 / 1024.0);
|
||||
|
||||
printf("\n--- Creating large vector ---\n");
|
||||
Vec8_t big = create(NULL);
|
||||
|
||||
printf("Adding elements...\n");
|
||||
for (size_t i = 0; i < 100000000; i++) {
|
||||
big = add_back(&big, 'x');
|
||||
if (i % 10000000 == 0) {
|
||||
printf(" %zu elements: %.2f MB\n", i+1, get_physical_mem() / 1024.0 / 1024.0);
|
||||
}
|
||||
}
|
||||
|
||||
printf(" Final: %zu elements, %.2f MB\n", big.size, get_physical_mem() / 1024.0 / 1024.0);
|
||||
|
||||
printf("\n--- BEFORE delete: %.2f MB ---\n", get_physical_mem() / 1024.0 / 1024.0);
|
||||
|
||||
delete(&big);
|
||||
|
||||
printf("--- AFTER delete: %.2f MB ---\n", get_physical_mem() / 1024.0 / 1024.0);
|
||||
|
||||
printf("\n--- Create 1000 vectors then delete ---\n");
|
||||
printf("Before: %.2f MB\n", get_physical_mem() / 1024.0 / 1024.0);
|
||||
|
||||
for (int c = 0; c < 1000; c++) {
|
||||
Vec8_t v = create(NULL);
|
||||
for (int i = 0; i < 100000; i++) {
|
||||
v = add_back(&v, 'x');
|
||||
}
|
||||
delete(&v);
|
||||
}
|
||||
|
||||
printf("After cycles: %.2f MB\n", get_physical_mem() / 1024.0 / 1024.0);
|
||||
|
||||
printf("\n--- RESULT ---\n");
|
||||
printf("Physical memory used: %.2f MB\n", get_physical_mem() / 1024.0 / 1024.0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user