summaryrefslogtreecommitdiff
path: root/src/util
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
parentd1233da64ae31a381fd484b446e87c2c55ed02b8 (diff)
fix mem leaks, string convenience funcs
Diffstat (limited to 'src/util')
-rw-r--r--src/util/allocator.h50
-rw-r--r--src/util/profiler.h4
-rw-r--r--src/util/string.h55
3 files changed, 96 insertions, 13 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 ) );
diff --git a/src/util/profiler.h b/src/util/profiler.h
index c8eea24..7caac96 100644
--- a/src/util/profiler.h
+++ b/src/util/profiler.h
@@ -66,10 +66,8 @@ inline void __profiler_intern_new_frame( PROFILER_LIST_ENTRY* entry ) {
return pe->hash == entry->hash;
} );
- if( i != -1 ) {
- __profiler_intern_clear_frame( &gprof.frames.data[i] );
+ if( i != -1 )
gprof.frames.erase( i );
- }
PROFILER_LIST_ENTRY* pne = gprof.frames.push( ne );
for( auto& it : pne->children ) {
diff --git a/src/util/string.h b/src/util/string.h
index 0781fca..04bd9c6 100644
--- a/src/util/string.h
+++ b/src/util/string.h
@@ -54,6 +54,14 @@ struct ARRSTR {
template <typename CT>
struct __str : public LIST<CT> {
__str() : LIST<CT>() {}
+ __str( U32 count, const CT* str ) : LIST<CT>() {
+ this->data = 0;
+ this->capacity = 0;
+ this->reserve( count * 2 );
+ memcpy( this->data, str, count );
+ this->size = count;
+ this->data[this->size] = 0;
+ }
__str( const CT* fmt, ... ) : LIST<CT>() {
va_list args;
va_start( args, fmt );
@@ -62,6 +70,7 @@ struct __str : public LIST<CT> {
U32 c = vsnprintf( 0, 0, fmt, args );
va_end( args );
this->data = 0;
+ this->capacity = 0;
this->reserve( c * 2 );
vsnprintf( this->data, c + 1, fmt, args2 );
this->data[c] = 0;
@@ -187,7 +196,10 @@ struct __str : public LIST<CT> {
return idx_of( str, 0 );
}
- U32 idx_of( const CT* str, U32 offset ) {
+ U32 idx_of( const CT* str, I32 offset ) {
+ if( offset < 0 )
+ offset = this->size + offset;
+
for( U32 i = offset; i < this->size; ++i ) {
U8 found = 1;
for( U32 i2 = 0; !!str[i2] && i + i2 < this->size; ++i2 ) {
@@ -217,6 +229,47 @@ struct __str : public LIST<CT> {
return 0;
}
+ LIST<__str<CT>> split( const char* where ) {
+ LIST<__str<CT>> ret;
+ U32 slen = strlen_ct( where );
+
+ U32 last = 0;
+ for( U32 i = 0; i < this->size; ++i ) {
+ for( U32 i2 = 0; i2 < slen; ++i2 ) {
+ if( this->data[i + i2] != where[i2] )
+ break;
+
+ if( i2 == slen - 1 ) {
+ if( !(last - i) )
+ ret.push( "" );
+ else
+ ret.push( __str<CT>( i - last, this->data + last ) );
+ i += slen;
+ last = i;
+ }
+ }
+ }
+
+ if( last < this->size - slen ) {
+ if( !( this->size - last ) )
+ ret.push( "" );
+ else
+ ret.push( __str<CT>( this->size - last, this->data + last ) );
+ }
+
+ return ret;
+ }
+
+ // can take negative input as offset from end
+ __str<CT> substr( I32 start, I32 end ) {
+ if( start < 0 )
+ start = this->size + start;
+ if( end < 0 )
+ end = this->size + end;
+
+ return __str<CT>( end - start, this->data + start );
+ }
+
LIST_ITERATOR<CT> end() {
return LIST_ITERATOR<CT>( this->data + this->size );
}