Fix memory leak in List, Map and Set
This commit is contained in:
parent
0307a1d9be
commit
fea3e44856
15
src/containers/List.h
Normal file → Executable file
15
src/containers/List.h
Normal file → Executable file
|
@ -32,6 +32,7 @@
|
|||
#include <cassert>
|
||||
#include <cstring>
|
||||
#include <iterator>
|
||||
#include <memory>
|
||||
|
||||
namespace reactphysics3d {
|
||||
|
||||
|
@ -204,8 +205,18 @@ class List {
|
|||
|
||||
if (mBuffer != nullptr) {
|
||||
|
||||
// Copy the elements to the new allocated memory location
|
||||
std::memcpy(newMemory, mBuffer, mSize * sizeof(T));
|
||||
if (mSize > 0) {
|
||||
|
||||
// Copy the elements to the new allocated memory location
|
||||
T* destination = static_cast<T*>(newMemory);
|
||||
T* items = static_cast<T*>(mBuffer);
|
||||
std::uninitialized_copy(items, items + mSize, destination);
|
||||
|
||||
// Destruct the previous items
|
||||
for (size_t i=0; i<mSize; i++) {
|
||||
items[i].~T();
|
||||
}
|
||||
}
|
||||
|
||||
// Release the previously allocated memory
|
||||
mAllocator.release(mBuffer, mCapacity * sizeof(T));
|
||||
|
|
24
src/containers/Map.h
Normal file → Executable file
24
src/containers/Map.h
Normal file → Executable file
|
@ -68,10 +68,16 @@ class Map {
|
|||
keyValue = nullptr;
|
||||
}
|
||||
|
||||
/// Copy-constructor
|
||||
Entry(const Entry& entry) {
|
||||
hashCode = entry.hashCode;
|
||||
next = entry.next;
|
||||
keyValue = entry.keyValue;
|
||||
}
|
||||
|
||||
/// Destructor
|
||||
~Entry() {
|
||||
|
||||
assert(keyValue == nullptr);
|
||||
}
|
||||
|
||||
};
|
||||
|
@ -155,8 +161,16 @@ class Map {
|
|||
newBuckets[i] = -1;
|
||||
}
|
||||
|
||||
// Copy the old entries to the new allocated memory location
|
||||
std::memcpy(newEntries, mEntries, mNbUsedEntries * sizeof(Entry));
|
||||
if (mNbUsedEntries > 0) {
|
||||
|
||||
// Copy the old entries to the new allocated memory location
|
||||
std::uninitialized_copy(mEntries, mEntries + mNbUsedEntries, newEntries);
|
||||
|
||||
// Destruct the old entries in the previous location
|
||||
for (int i=0; i < mNbUsedEntries; i++) {
|
||||
mEntries[i].~Entry();
|
||||
}
|
||||
}
|
||||
|
||||
// Construct the new entries
|
||||
for (int i=mNbUsedEntries; i<newCapacity; i++) {
|
||||
|
@ -391,7 +405,7 @@ class Map {
|
|||
mEntries = static_cast<Entry*>(mAllocator.allocate(mCapacity * sizeof(Entry)));
|
||||
|
||||
// Copy the buckets
|
||||
std::memcpy(mBuckets, map.mBuckets, mCapacity * sizeof(int));
|
||||
std::uninitialized_copy(map.mBuckets, map.mBuckets + mCapacity, mBuckets);
|
||||
|
||||
// Copy the entries
|
||||
for (int i=0; i < mCapacity; i++) {
|
||||
|
@ -710,7 +724,7 @@ class Map {
|
|||
mEntries = static_cast<Entry*>(mAllocator.allocate(mCapacity * sizeof(Entry)));
|
||||
|
||||
// Copy the buckets
|
||||
std::memcpy(mBuckets, map.mBuckets, mCapacity * sizeof(int));
|
||||
std::uninitialized_copy(map.mBuckets, map.mBuckets + mCapacity, mBuckets);
|
||||
|
||||
// Copy the entries
|
||||
for (int i=0; i < mCapacity; i++) {
|
||||
|
|
24
src/containers/Set.h
Normal file → Executable file
24
src/containers/Set.h
Normal file → Executable file
|
@ -67,10 +67,16 @@ class Set {
|
|||
value = nullptr;
|
||||
}
|
||||
|
||||
/// Copy-constructor
|
||||
Entry(const Entry& entry) {
|
||||
hashCode = entry.hashCode;
|
||||
next = entry.next;
|
||||
value = entry.value;
|
||||
}
|
||||
|
||||
/// Destructor
|
||||
~Entry() {
|
||||
|
||||
assert(value == nullptr);
|
||||
}
|
||||
|
||||
};
|
||||
|
@ -154,8 +160,16 @@ class Set {
|
|||
newBuckets[i] = -1;
|
||||
}
|
||||
|
||||
// Copy the old entries to the new allocated memory location
|
||||
std::memcpy(newEntries, mEntries, mNbUsedEntries * sizeof(Entry));
|
||||
if (mNbUsedEntries > 0) {
|
||||
|
||||
// Copy the old entries to the new allocated memory location
|
||||
std::uninitialized_copy(mEntries, mEntries + mNbUsedEntries, newEntries);
|
||||
|
||||
// Destruct the old entries at previous location
|
||||
for (int i=0; i<mNbUsedEntries; i++) {
|
||||
mEntries[i].~Entry();
|
||||
}
|
||||
}
|
||||
|
||||
// Construct the new entries
|
||||
for (int i=mNbUsedEntries; i<newCapacity; i++) {
|
||||
|
@ -390,7 +404,7 @@ class Set {
|
|||
mEntries = static_cast<Entry*>(mAllocator.allocate(mCapacity * sizeof(Entry)));
|
||||
|
||||
// Copy the buckets
|
||||
std::memcpy(mBuckets, set.mBuckets, mCapacity * sizeof(int));
|
||||
std::uninitialized_copy(set.mBuckets, set.mBuckets + mCapacity, mBuckets);
|
||||
|
||||
// Copy the entries
|
||||
for (int i=0; i < mCapacity; i++) {
|
||||
|
@ -651,7 +665,7 @@ class Set {
|
|||
mEntries = static_cast<Entry*>(mAllocator.allocate(mCapacity * sizeof(Entry)));
|
||||
|
||||
// Copy the buckets
|
||||
std::memcpy(mBuckets, set.mBuckets, mCapacity * sizeof(int));
|
||||
std::uninitialized_copy(set.mBuckets, set.mBuckets + mCapacity, mBuckets);
|
||||
|
||||
// Copy the entries
|
||||
for (int i=0; i < mCapacity; i++) {
|
||||
|
|
Loading…
Reference in New Issue
Block a user