From 08cdf72330276a4b4883fea41c3ada1087800a41 Mon Sep 17 00:00:00 2001 From: Jonathan Bradley Date: Fri, 8 Sep 2023 16:43:06 -0400 Subject: Use move operator for DynArray::Push The EventBucket struct has a DynArray as a member. Calling ::Push({}) instantiates a new item and thus a new DynArray. When the new `{}` object goes out of scope, the DynArray destructor was being called, invalidating the data pointer. This commit ensures that if the object is cloned or moved, the pointer, which now lives in the outer array, remains valid. --- src/dynamic-array.hpp | 44 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 42 insertions(+), 2 deletions(-) (limited to 'src/dynamic-array.hpp') diff --git a/src/dynamic-array.hpp b/src/dynamic-array.hpp index 978e291..f06ddac 100644 --- a/src/dynamic-array.hpp +++ b/src/dynamic-array.hpp @@ -11,7 +11,7 @@ #define BAKE_DYN_ARRAY(T) template struct DynArray; struct DynArrayBase { - char *ptr = nullptr; + mutable char *ptr = nullptr; int64_t elementSize = 0; int64_t elementCount = 0; int64_t reservedCount = 0; @@ -21,6 +21,10 @@ template struct DynArray: DynArrayBase { DynArray(); explicit DynArray(int64_t reserveCount); + DynArray(const DynArray &other); + DynArray(DynArray &&other); + DynArray &operator=(const DynArray &other); + DynArray &operator=(DynArray &&other); ~DynArray(); T &operator[](std::size_t index); T *GetPtr(); @@ -50,6 +54,40 @@ template inline DynArray::DynArray() { this->elementSize = sizeof(T); } +template inline DynArray::DynArray(const DynArray &rh) { + this->ptr = rh.ptr; + this->elementSize = rh.elementSize; + this->elementCount = rh.elementCount; + this->reservedCount = rh.reservedCount; + rh.ptr = nullptr; +} + +template inline DynArray::DynArray(DynArray &&rh) { + this->ptr = rh.ptr; + this->elementSize = rh.elementSize; + this->elementCount = rh.elementCount; + this->reservedCount = rh.reservedCount; + rh.ptr = nullptr; +} + +template inline DynArray &DynArray::operator=(const DynArray &rh) { + this->ptr = rh.ptr; + this->elementSize = rh.elementSize; + this->elementCount = rh.elementCount; + this->reservedCount = rh.reservedCount; + rh.ptr = nullptr; + return *this; +} + +template inline DynArray &DynArray::operator=(DynArray &&rh) { + this->ptr = rh.ptr; + this->elementSize = rh.elementSize; + this->elementCount = rh.elementCount; + this->reservedCount = rh.reservedCount; + rh.ptr = nullptr; + return *this; +} + template inline DynArray::~DynArray() { DynArrayDestroy(this); } @@ -81,7 +119,9 @@ template inline void DynArray::Push(const T &val) { auto safeReserveCount = this->reservedCount == 0 ? 1 : this->reservedCount; DynArrayReserve(this, int64_t(safeReserveCount * 1.5)); } - std::memcpy(this->ptr + (sizeof(T) * this->elementCount), &val, sizeof(T)); + auto itemPtr = this->ptr + (sizeof(T) * this->elementCount); + auto &targetItem = *reinterpret_cast(itemPtr); + targetItem = val; this->elementCount += 1; } -- cgit v1.2.3