Compare commits

..

3 Commits

Author SHA1 Message Date
Sara 253cc0cb0c feat: added list_with_len and list_from_type_with_len 2024-01-26 12:02:56 +01:00
Sara cb0858f14f fix: critical, fixed list_empty not actually freeing the allocated list
leading to orphanned memory
2024-01-26 12:01:41 +01:00
Sara b38362c2aa feat: added list_set_len
to set the length of the array
2024-01-26 11:49:49 +01:00
2 changed files with 23 additions and 13 deletions

27
list.c
View File

@ -4,32 +4,34 @@
#include "string.h" #include "string.h"
#include "debug.h" #include "debug.h"
#ifndef LIST_DEFAULT_RESERVE
#define LIST_DEFAULT_RESERVE 4 #define LIST_DEFAULT_RESERVE 4
#endif
List list_init(size_t element_size) { List list_init(size_t element_size) {
return list_with_len(element_size, 0);
}
List list_with_len(size_t element_size, size_t len) {
List self = { List self = {
.element_size = element_size, .element_size = element_size,
.cap = LIST_DEFAULT_RESERVE, .cap = 0,
.len = 0, .len = 0,
.data = malloc(element_size * LIST_DEFAULT_RESERVE), .data = NULL,
}; };
if(len != 0) {
list_set_len(&self, len);
if (self.data == NULL) { if (self.data == NULL) {
LOG_ERROR("Failed to allocate list with starting capacity of %d", LIST_DEFAULT_RESERVE); LOG_ERROR("Failed to allocate list with starting capacity of %d", LIST_DEFAULT_RESERVE);
self.cap = 0; self.cap = 0;
} }
}
return self; return self;
} }
List list_copy(const List* source) { List list_copy(const List* source) {
List self = list_init(source->element_size); List self = list_init(source->element_size);
list_reserve(&self, source->cap); list_set_len(&self, source->cap);
if(self.cap > 0) { if(self.cap > 0) {
memcpy(self.data, source->data, source->element_size * source->len); memcpy(self.data, source->data, source->element_size * source->len);
self.len = source->len;
} else { } else {
LOG_ERROR("Failed to reserve space"); LOG_ERROR("Failed to reserve space");
} }
@ -37,8 +39,8 @@ List list_copy(const List* source) {
} }
void list_empty(List* self) { void list_empty(List* self) {
if(self->data == NULL || self->cap == 0) if(self->data != NULL && self->cap != 0)
return; free(self->data);
self->data = NULL; self->data = NULL;
self->cap = 0; self->cap = 0;
self->len = 0; self->len = 0;
@ -64,6 +66,11 @@ void list_reserve(List* self, size_t at_least) {
self->cap = new_cap; self->cap = new_cap;
} }
void list_set_len(List* self, size_t len) {
list_reserve(self, len);
self->len = len;
}
void* list_at_unchecked(List* self, size_t at) { void* list_at_unchecked(List* self, size_t at) {
union { union {
uint8_t* as_byte; uint8_t* as_byte;

3
list.h
View File

@ -13,10 +13,12 @@ struct List {
}; };
extern List list_init(size_t element_size); extern List list_init(size_t element_size);
extern List list_with_len(size_t element_size, size_t len);
extern List list_copy(const List* source); extern List list_copy(const List* source);
extern void list_empty(List* list); extern void list_empty(List* list);
extern void list_reserve(List* self, size_t at_least); extern void list_reserve(List* self, size_t at_least);
extern void list_set_len(List* self, size_t len);
extern void* list_at(List* list, size_t at); extern void* list_at(List* list, size_t at);
extern void* list_at_unchecked(List* self, size_t at); extern void* list_at_unchecked(List* self, size_t at);
@ -30,6 +32,7 @@ extern void* list_iterator_end(List* self);
extern size_t list_contains(List* self, void* query); extern size_t list_contains(List* self, void* query);
#define list_from_type(T) list_init(sizeof(T)) #define list_from_type(T) list_init(sizeof(T))
#define list_from_type_with_len(T, __len) list_with_len(sizeof(T), __len)
#define list_foreach(T, iter, list) for(T iter = list_iterator_begin(list); iter != (T)list_iterator_end(list); ++iter) #define list_foreach(T, iter, list) for(T iter = list_iterator_begin(list); iter != (T)list_iterator_end(list); ++iter)
#define list_at_as(T, __list, __i) ((T*)(list_at(__list, __i))) #define list_at_as(T, __list, __i) ((T*)(list_at(__list, __i)))