Selaa lähdekoodia

core: call destructors

Daniele Bartolini 4 kuukautta sitten
vanhempi
sitoutus
af92c4c609

+ 1 - 0
docs/changelog.rst

@@ -47,6 +47,7 @@ Changelog
 * Runtime: fixed camera components not getting destroyed.
 * Runtime: fixed range-based culling of sound sources.
 * Runtime: fixed collision begin/stay generation.
+* Compiler: fixed a memory leak when compiling units or levels with deleted components.
 
 0.58.0 --- 01 Aug 2025
 ----------------------

+ 9 - 4
src/core/containers/hash_map.inl

@@ -363,16 +363,17 @@ inline HashMap<TKey, TValue, Hash, KeyEqual>::~HashMap()
 template<typename TKey, typename TValue, typename Hash, typename KeyEqual>
 HashMap<TKey, TValue, Hash, KeyEqual> &HashMap<TKey, TValue, Hash, KeyEqual>::operator=(const HashMap<TKey, TValue, Hash, KeyEqual> &other)
 {
-	_capacity = other._capacity;
-	_size = other._size;
-	_mask = other._mask;
+	for (u32 i = 0; i < _capacity; ++i) {
+		if (_index[i].index == 0x0123abcd)
+			_data[i].~Pair();
+	}
 
 	if (other._capacity > 0) {
 		_allocator->deallocate(_buffer);
 		const u32 size = other._capacity * (sizeof(Index) + sizeof(Entry)) + alignof(Index) + alignof(Entry);
 		_buffer = (char *)_allocator->allocate(size);
 		_index = (Index *)memory::align_top(_buffer, alignof(Index));
-		_data = (Entry *)memory::align_top(_index + _capacity, alignof(Entry));
+		_data = (Entry *)memory::align_top(_index + other._capacity, alignof(Entry));
 
 		memcpy(_index, other._index, sizeof(Index)*other._capacity);
 		for (u32 i = 0; i < other._capacity; ++i) {
@@ -383,6 +384,10 @@ HashMap<TKey, TValue, Hash, KeyEqual> &HashMap<TKey, TValue, Hash, KeyEqual>::op
 			}
 		}
 	}
+
+	_capacity = other._capacity;
+	_size = other._size;
+	_mask = other._mask;
 	return *this;
 }
 

+ 9 - 4
src/core/containers/hash_set.inl

@@ -341,16 +341,17 @@ inline HashSet<TKey, Hash, KeyEqual>::~HashSet()
 template<typename TKey, typename Hash, typename KeyEqual>
 HashSet<TKey, Hash, KeyEqual> &HashSet<TKey, Hash, KeyEqual>::operator=(const HashSet<TKey, Hash, KeyEqual> &other)
 {
-	_capacity = other._capacity;
-	_size = other._size;
-	_mask = other._mask;
+	for (u32 i = 0; i < _capacity; ++i) {
+		if (_index[i].index == 0x0123abcd)
+			_data[i].~TKey();
+	}
 
 	if (other._capacity > 0) {
 		_allocator->deallocate(_buffer);
 		const u32 size = other._capacity * (sizeof(Index) + sizeof(TKey)) + alignof(Index) + alignof(TKey);
 		_buffer = (char *)_allocator->allocate(size);
 		_index = (Index *)memory::align_top(_buffer, alignof(Index));
-		_data = (TKey *)memory::align_top(_index + _capacity, alignof(TKey));
+		_data = (TKey *)memory::align_top(_index + other._capacity, alignof(TKey));
 
 		memcpy(_index, other._index, sizeof(Index)*other._capacity);
 		for (u32 i = 0; i < other._capacity; ++i) {
@@ -361,6 +362,10 @@ HashSet<TKey, Hash, KeyEqual> &HashSet<TKey, Hash, KeyEqual>::operator=(const Ha
 			}
 		}
 	}
+
+	_capacity = other._capacity;
+	_size = other._size;
+	_mask = other._mask;
 	return *this;
 }
 

+ 18 - 0
src/core/unit_tests.cpp

@@ -182,6 +182,15 @@ static void test_hash_map()
 		hash_map::set(ma, 0, 0);
 		ma = mb;
 	}
+	{
+		Vector<int> v(default_allocator());
+		vector::push_back(v, 0);
+		HashMap<int, Vector<int>> a(default_allocator());
+		HashMap<int, Vector<int>> b(default_allocator());
+		hash_map::set(a, 0, v);
+		hash_map::set(b, 0, v);
+		a = b;
+	}
 	memory_globals::shutdown();
 }
 
@@ -235,6 +244,15 @@ static void test_hash_set()
 		hash_set::insert(ma, 0);
 		ma = mb;
 	}
+	{
+		DynamicString str(default_allocator());
+		str = "test";
+		HashSet<DynamicString> a(default_allocator());
+		HashSet<DynamicString> b(default_allocator());
+		hash_set::insert(a, str);
+		hash_set::insert(b, str);
+		a = b;
+	}
 	memory_globals::shutdown();
 }