Implemented lz_da_remove and a memory analysis tool

This commit is contained in:
cannoli-fruit 2026-07-24 21:59:11 -04:00
commit 5a41640054
3 changed files with 131 additions and 0 deletions

21
examples/da_remove.c Normal file
View file

@ -0,0 +1,21 @@
#include <stdio.h>
#define LAZY_IMPL
#include "../lazy.h"
int main() {
int arr[] = {0,1,2,3,4};
Lz_DA(int) da = {0};
lz_da_fill_from_array(&da, arr);
lz_da_foreach(int, x, da) {
printf("%d\n", *x);
}
lz_da_remove(da, 2);
lz_da_foreach(int, x, da) {
printf("%d\n", *x);
}
return 0;
}

34
examples/leak.c Normal file
View file

@ -0,0 +1,34 @@
#include <stdio.h>
#define LZ_MEM_ANALYZER
#define LAZY_IMPL
#include "../lazy.h"
typedef struct {
int payload;
void *next;
} LLNode;
int main () {
LLNode *root = malloc(sizeof(LLNode));
LLNode *curr = root;
int prevX = 0;
for (int i = 0; i < 10; ++i) {
LLNode *new = malloc(sizeof(LLNode));
curr->next = new;
new->payload = ++prevX;
curr = new;
}
curr = root;
while (curr->next) {
void *next = curr->next;
printf("%d\n", curr->payload);
free(curr);
curr = next;
}
free(curr);
lz_mem_debug();
return 0;
}

76
lazy.h
View file

@ -1,4 +1,5 @@
#include <stddef.h> #include <stddef.h>
#include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <assert.h> #include <assert.h>
@ -27,6 +28,17 @@ typedef struct {
size_t cnt; size_t cnt;
size_t cap; size_t cap;
} Lz_SB; } Lz_SB;
#endif
#ifndef LZ_ALLOC_DATA_DEF
#define LZ_ALLOC_DATA_DEF
typedef struct {
size_t size;
void *ptr;
char file[256];
int line;
} Lz_Alloc_Data;
#endif #endif
void lz_slc_trim_left_typ(Lz_Slc *src, int (*classfunc)(int)); void lz_slc_trim_left_typ(Lz_Slc *src, int (*classfunc)(int));
@ -116,6 +128,16 @@ long long lz_slc_atoll(Lz_Slc *src);
} while(0) } while(0)
#endif #endif
#ifndef lz_da_remove
#define lz_da_remove(da, idx) do {\
if ((da).cnt <= (idx)) {\
assert(0 && "Removal index out of bounds");\
}\
--(da).cnt;\
memmove((da).data+idx,(da).data+idx+1,((da).cnt-idx)*sizeof(*(da.data)));\
} while(0)
#endif
#ifndef lz_da_destroy #ifndef lz_da_destroy
#define lz_da_destroy(da) do { free((da).data); } while (0); #define lz_da_destroy(da) do { free((da).data); } while (0);
#endif #endif
@ -284,6 +306,8 @@ long long lz_sb_atoll(Lz_SB *src);
#ifdef LAZY_IMPL #ifdef LAZY_IMPL
#undef LAZY_IMPL #undef LAZY_IMPL
Lz_DA(Lz_Alloc_Data) _lz_allocations = {0};
size_t lz_hm_hash_raw_bytes(size_t cap, void *key, size_t k_s) { size_t lz_hm_hash_raw_bytes(size_t cap, void *key, size_t k_s) {
size_t hash = 0; size_t hash = 0;
for (size_t i = 0; i < k_s; ++i) { for (size_t i = 0; i < k_s; ++i) {
@ -523,4 +547,56 @@ long long lz_sb_atoll(Lz_SB *src) {
free(cstr); free(cstr);
return x; return x;
} }
void *lz_tracking_malloc(size_t size, const char* file, int line) {
void *ptr = malloc(size);
Lz_Alloc_Data dat = (Lz_Alloc_Data){
.size = size,
.ptr = ptr,
.line = line
};
strncpy(dat.file, file, 256);
lz_da_append(_lz_allocations, dat);
return ptr;
}
void lz_tracking_free(void *ptr, const char *file, int line) {
for (int i = 0; i < _lz_allocations.cnt; ++i) {
if (_lz_allocations.data[i].ptr == ptr) {
lz_da_remove(_lz_allocations, i);
free(ptr);
return;
}
}
printf("[LZ_MEM_ANALYZER] Freeing unallocated memory @ %x, %s, line %d",
ptr, file, line);
exit(1);
}
void lz_mem_analyzer_debug(const char *file, int line) {
printf("[LZ_MEM_ANALYZER] Memory report from %s, line %d\n", file, line);
if (_lz_allocations.cnt == 0) {
printf("All tests passed :)\n");
return;
}
printf("Found %d unfreed chunks of memory\n", _lz_allocations.cnt);
for (int i = 0; i < _lz_allocations.cnt; ++i) {
Lz_Alloc_Data dat = _lz_allocations.data[i];
printf("Non-freed memory found: %x\n", dat.ptr);
printf(" size: %d bytes\n", dat.size);
printf(" allocated at:\n");
printf(" %s, line %d\n", dat.file, dat.line);
}
}
#endif
#ifdef LZ_MEM_ANALYZER
#undef LZ_MEM_ANALYZER
// TODO: implement the other memory functions (calloc and some others)
#define malloc(size) lz_tracking_malloc(size, __FILE__, __LINE__)
#define free(ptr) lz_tracking_free(ptr, __FILE__, __LINE__)
#define lz_mem_debug() lz_mem_analyzer_debug(__FILE__, __LINE__)
#else
#define lz_mem_debug()
#endif #endif