Browse Source

Free memory when calling shrink_to_fit on empty array (#1093)

Jorrit Rouwe 1 year ago
parent
commit
534e48c7de
3 changed files with 30 additions and 1 deletions
  1. 12 1
      Jolt/Core/Array.h
  2. 4 0
      Jolt/Core/Memory.cpp
  3. 14 0
      UnitTests/Core/ArrayTest.cpp

+ 12 - 1
Jolt/Core/Array.h

@@ -315,8 +315,19 @@ public:
 	/// Reduce the capacity of the array to match its size
 	void					shrink_to_fit()
 	{
-		if (mCapacity > mSize)
+		if (mSize == 0)
 		{
+			// Free memory block
+			if (mElements != nullptr)
+			{
+				get_allocator().deallocate(mElements, mCapacity);
+				mElements = nullptr;
+				mCapacity = 0;
+			}
+		}
+		else if (mCapacity > mSize)
+		{
+			// Reallocate memory block
 			pointer pointer = get_allocator().allocate(mSize);
 			move(pointer, mElements, mSize);
 			get_allocator().deallocate(mElements, mCapacity);

+ 4 - 0
Jolt/Core/Memory.cpp

@@ -21,11 +21,13 @@ JPH_NAMESPACE_BEGIN
 
 JPH_ALLOC_SCOPE void *JPH_ALLOC_FN(Allocate)(size_t inSize)
 {
+	JPH_ASSERT(inSize > 0);
 	return malloc(inSize);
 }
 
 JPH_ALLOC_SCOPE void *JPH_ALLOC_FN(Reallocate)(void *inBlock, size_t inSize)
 {
+	JPH_ASSERT(inSize > 0);
 	return realloc(inBlock, inSize);
 }
 
@@ -36,6 +38,8 @@ JPH_ALLOC_SCOPE void JPH_ALLOC_FN(Free)(void *inBlock)
 
 JPH_ALLOC_SCOPE void *JPH_ALLOC_FN(AlignedAllocate)(size_t inSize, size_t inAlignment)
 {
+	JPH_ASSERT(inSize > 0 && inAlignment > 0);
+
 #if defined(JPH_PLATFORM_WINDOWS)
 	// Microsoft doesn't implement posix_memalign
 	return _aligned_malloc(inSize, inAlignment);

+ 14 - 0
UnitTests/Core/ArrayTest.cpp

@@ -344,6 +344,12 @@ TEST_SUITE("ArrayTest")
 		Array<int> arr;
 		CHECK(arr.size() == 0);
 		CHECK(arr.capacity() == 0);
+		CHECK(arr.data() == nullptr);
+
+		arr.resize(0);
+		CHECK(arr.size() == 0);
+		CHECK(arr.capacity() == 0);
+		CHECK(arr.data() == nullptr);
 
 		arr.resize(123);
 		CHECK(arr.size() == 123);
@@ -446,6 +452,14 @@ TEST_SUITE("ArrayTest")
 		CHECK(arr.size() == 5);
 		for (int i = 0; i < 5; ++i)
 			CHECK(arr[i] == i);
+
+		arr.clear();
+		CHECK(arr.capacity() == 5);
+		CHECK(arr.size() == 0);
+
+		arr.shrink_to_fit();
+		CHECK(arr.capacity() == 0);
+		CHECK(arr.data() == nullptr);
 	}
 
 	TEST_CASE("TestShrinkToFitNonTriv")