summaryrefslogtreecommitdiff
path: root/src/util/allocator.h
diff options
context:
space:
mode:
authoraura <nw@moneybot.cc>2026-03-11 00:41:44 +0100
committeraura <nw@moneybot.cc>2026-03-11 00:41:44 +0100
commit4c0ab7a739085a32688f34947c0b1812a31d92d7 (patch)
tree3b32fa706a61438160433c51585c8d3a70a5ab88 /src/util/allocator.h
parentd1233da64ae31a381fd484b446e87c2c55ed02b8 (diff)
fix mem leaks, string convenience funcs
Diffstat (limited to 'src/util/allocator.h')
-rw-r--r--src/util/allocator.h50
1 files changed, 41 insertions, 9 deletions
diff --git a/src/util/allocator.h b/src/util/allocator.h
index 64bad23..8b159da 100644
--- a/src/util/allocator.h
+++ b/src/util/allocator.h
@@ -93,9 +93,15 @@ struct LIST {
}
data = (T*)malloc( sizeof( T ) * other.capacity );
- memcpy( data, other.data, other.size * sizeof( T ) );
size = other.size;
capacity = other.capacity;
+ if constexpr( __is_trivially_copyable(T) )
+ memcpy( data, other.data, other.size * sizeof(T) );
+ else {
+ memset( data, 0, other.capacity * sizeof(T) );
+ for( U32 i = 0; i < other.size; i++ )
+ data[i] = other.data[i];
+ }
}
LIST<T>& operator=( const LIST<T>& other ) {
@@ -107,7 +113,7 @@ struct LIST {
data = 0;
- if( !other.capacity || !other.size ) {
+ if( !other.capacity || !other.size || !other.data ) {
capacity = 1;
size = 0;
data = (T*)malloc( sizeof( T ) );
@@ -116,15 +122,26 @@ struct LIST {
}
data = (T*)malloc( other.capacity * sizeof( T ) );
- memcpy( data, other.data, other.size * sizeof( T ) );
size = other.size;
capacity = other.capacity;
+ if constexpr( __is_trivially_copyable(T) )
+ memcpy( data, other.data, other.size * sizeof(T) );
+ else {
+ memset( data, 0, other.capacity * sizeof(T) );
+ for( U32 i = 0; i < other.size; i++ )
+ data[i] = other.data[i];
+ }
return *this;
}
~LIST() {
- free( data );
+ if constexpr( !__is_trivially_destructible(T) ) {
+ for( U32 i = 0; i < size; i++ )
+ data[i].~T();
+ }
+ if( data )
+ free( data );
}
T at( U32 index ) {
@@ -136,7 +153,7 @@ struct LIST {
return;
T* newblock = (T*)malloc( count * sizeof( T ) );
- memset( newblock, 0, capacity * sizeof( T ) );
+ memset( newblock, 0, count * sizeof( T ) );
if( data ) {
memcpy( newblock, data, size * sizeof( T ) );
free( data );
@@ -221,9 +238,14 @@ struct LIST {
// slow - pushes every item individually, calls copy constructors
void push_list( LIST<T>& list ) {
- list.each( fn( T* item ) {
- push( *item );
- } );
+ if constexpr( __is_trivially_copyable(T) ) {
+ emplace_list( list );
+ } else {
+ reserve( list.capacity );
+ list.each( fn( T* item ) {
+ push( *item );
+ } );
+ }
}
T pop() {
@@ -241,7 +263,7 @@ struct LIST {
}
T pop_front() {
- if( size == 0 ) {
+ if( size == 0 ) {
dlog( "LIST::pop_front() : called on empty list\n" );
abort();
return {};
@@ -256,6 +278,11 @@ struct LIST {
if( idx >= size )
return;
+ if constexpr( !__is_trivially_destructible(T) ) {
+ data[idx].~T();
+ memset( &data[idx], 0, sizeof(T) );
+ }
+
for( U32 i = idx; i < size - 1; i++ )
data[i] = data[i + 1];
@@ -268,6 +295,11 @@ struct LIST {
}
void clear() {
+ if constexpr( !__is_trivially_destructible(T) ) {
+ for( U32 i = 0; i < size; ++i )
+ data[i].~T();
+ }
+
size = 0;
free( data );
data = (T*)malloc( sizeof( T ) );