Fix array resize crash on 0 initialisation
This commit is contained in:
parent
8209593f57
commit
5876c16abe
58
dqn.h
58
dqn.h
@ -274,9 +274,9 @@ public:
|
||||
|
||||
typedef u8 *Allocator(DqnMemAPI::Request request);
|
||||
|
||||
static Request RequestRealloc(const DqnMemAPI memAPI, void *const oldMemPtr, const size_t oldSize, const size_t newSize);
|
||||
static Request RequestAlloc (const DqnMemAPI memAPI, const size_t size, const bool clearToZero);
|
||||
static Request RequestFree (const DqnMemAPI memAPI, void *const ptrToFree, const size_t sizeToFree);
|
||||
static Request RequestRealloc(const DqnMemAPI memAPI, void *const oldMemPtr, size_t const oldSize, size_t const newSize);
|
||||
static Request RequestAlloc (const DqnMemAPI memAPI, size_t const size, const bool clearToZero = true);
|
||||
static Request RequestFree (const DqnMemAPI memAPI, void *const ptrToFree, size_t const sizeToFree);
|
||||
|
||||
bool IsValid() const { return (callback != nullptr); }
|
||||
|
||||
@ -349,17 +349,17 @@ struct DqnMemStack
|
||||
// mem: Memory to use for the memory stack
|
||||
// byteAlign: Set the alignment of memory addresses for all allocated items from the memory stack.
|
||||
// return: FALSE if args are invalid, or insufficient memSize.
|
||||
bool InitWithFixedMem(u8 *const mem, const size_t memSize, const u32 byteAlign_ = 4);
|
||||
bool InitWithFixedMem(u8 *const mem, size_t const memSize, u32 const byteAlign_ = 4);
|
||||
|
||||
// The memory stack uses 1 initial allocation from the DqnMem_Alloc(). No further allocations are
|
||||
// made. All allocations are suballocated from the first allocation.
|
||||
// size: The amount of memory to allocate. Size gets aligned to the next "byteAlign"ed value.
|
||||
bool InitWithFixedSize(const size_t size, const bool zeroClear, const u32 byteAlign_ = 4, const DqnMemAPI memAPI_ = DqnMemAPI_HeapAllocator());
|
||||
bool InitWithFixedSize(size_t const size, bool const zeroClear, u32 const byteAlign_ = 4, DqnMemAPI const memAPI_ = DqnMemAPI_HeapAllocator());
|
||||
|
||||
// Dynamically expandable stack. Akin to DqnMemStack_InitWithFixedSize() except if the MemStack does
|
||||
// not have enough space for allocation it will automatically attach another MemBlock using
|
||||
// DqnMem_Calloc().
|
||||
bool Init(const size_t size, const bool zeroClear, const u32 byteAlign_ = 4, const DqnMemAPI memAPI_ = DqnMemAPI_HeapAllocator());
|
||||
bool Init(size_t const size, bool const zeroClear, u32 const byteAlign_ = 4, DqnMemAPI const memAPI_ = DqnMemAPI_HeapAllocator());
|
||||
|
||||
// -- Memory API
|
||||
// Allocate memory from the MemStack.
|
||||
@ -382,7 +382,7 @@ struct DqnMemStack
|
||||
bool FreeLastBlock();
|
||||
|
||||
// Reset the current memory block usage to 0.
|
||||
void ClearCurrBlock(const bool zeroClear);
|
||||
void ClearCurrBlock(bool const zeroClear);
|
||||
|
||||
// -- Temporary Regions API
|
||||
// region: Takes pointer to a zero-cleared DqnMemStackTempRegion struct.
|
||||
@ -396,7 +396,7 @@ struct DqnMemStack
|
||||
// -- Advanced API
|
||||
// These are useful for forcing a new block to be used. AllocateCompatibleBlock() will fail if the
|
||||
// supplied stack has flags set such that the stack is not allowed to have new blocks.
|
||||
Block *AllocateCompatibleBlock(size_t size, const bool zeroClear);
|
||||
Block *AllocateCompatibleBlock(size_t size, bool const zeroClear);
|
||||
bool AttachBlock (Block *const newBlock);
|
||||
bool DetachBlock (Block *const detachBlock);
|
||||
|
||||
@ -639,8 +639,16 @@ bool DqnArray<T>::Resize(i64 newMax)
|
||||
i64 oldSize = this->max * sizeof(T);
|
||||
i64 newSize = newMax * sizeof(T);
|
||||
|
||||
DqnMemAPI::Request info =
|
||||
DqnMemAPI::RequestRealloc(this->memAPI, this->data, oldSize, newSize);
|
||||
DqnMemAPI::Request info;
|
||||
if (oldSize == 0)
|
||||
{
|
||||
info = DqnMemAPI::RequestAlloc(this->memAPI, newSize, /*zeroClear*/ false);
|
||||
}
|
||||
else
|
||||
{
|
||||
info = DqnMemAPI::RequestRealloc(this->memAPI, this->data, oldSize, newSize);
|
||||
}
|
||||
|
||||
u8 *result = this->memAPI.callback(info);
|
||||
if (result)
|
||||
{
|
||||
@ -3049,8 +3057,8 @@ FILE_SCOPE u8 *DqnMemAPIInternal_StackAllocatorCallback(DqnMemAPI::Request info)
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// #DqnMemAPI Implementation
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
DqnMemAPI::Request DqnMemAPI::RequestRealloc(const DqnMemAPI memAPI, void *const oldMemPtr,
|
||||
const size_t oldSize, const size_t newSize)
|
||||
DqnMemAPI::Request DqnMemAPI::RequestRealloc(DqnMemAPI const memAPI, void *const oldMemPtr,
|
||||
size_t const oldSize, size_t const newSize)
|
||||
{
|
||||
DqnMemAPI::Request info = {};
|
||||
info.type = Type::Realloc;
|
||||
@ -3062,8 +3070,8 @@ DqnMemAPI::Request DqnMemAPI::RequestRealloc(const DqnMemAPI memAPI, void *const
|
||||
return info;
|
||||
}
|
||||
|
||||
DqnMemAPI::Request DqnMemAPI::RequestAlloc(const DqnMemAPI memAPI, const size_t size,
|
||||
const bool clearToZero = true)
|
||||
DqnMemAPI::Request DqnMemAPI::RequestAlloc(DqnMemAPI const memAPI, size_t const size,
|
||||
bool const clearToZero)
|
||||
{
|
||||
DqnMemAPI::Request result = {};
|
||||
result.type = DqnMemAPI::Type::Alloc;
|
||||
@ -3073,8 +3081,8 @@ DqnMemAPI::Request DqnMemAPI::RequestAlloc(const DqnMemAPI memAPI, const size_t
|
||||
return result;
|
||||
}
|
||||
|
||||
DqnMemAPI::Request DqnMemAPI::RequestFree(const DqnMemAPI memAPI, void *const ptrToFree,
|
||||
const size_t sizeToFree)
|
||||
DqnMemAPI::Request DqnMemAPI::RequestFree(DqnMemAPI const memAPI, void *const ptrToFree,
|
||||
size_t const sizeToFree)
|
||||
{
|
||||
DqnMemAPI::Request result = {};
|
||||
result.type = DqnMemAPI::Type::Free;
|
||||
@ -3105,8 +3113,8 @@ DQN_FILE_SCOPE DqnMemAPI DqnMemAPI_StackAllocator(DqnMemStack *const stack)
|
||||
// #DqnMemStackInternal Implementation
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
DQN_FILE_SCOPE DqnMemStack::Block *DqnMemStackInternal_AllocateBlock(u32 byteAlign, size_t size,
|
||||
const bool zeroClear,
|
||||
const DqnMemAPI &memAPI)
|
||||
bool const zeroClear,
|
||||
DqnMemAPI const &memAPI)
|
||||
{
|
||||
if (!memAPI.callback) return nullptr;
|
||||
|
||||
@ -3129,8 +3137,8 @@ DQN_FILE_SCOPE DqnMemStack::Block *DqnMemStackInternal_AllocateBlock(u32 byteAli
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// #DqnMemStack Initialisation Implementation
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
DQN_FILE_SCOPE bool DqnMemStack::InitWithFixedMem(u8 *const mem, const size_t memSize,
|
||||
const u32 byteAlign_)
|
||||
DQN_FILE_SCOPE bool DqnMemStack::InitWithFixedMem(u8 *const mem, size_t const memSize,
|
||||
u32 const byteAlign_)
|
||||
{
|
||||
// TODO(doyle): Logging
|
||||
if (!mem) return false;
|
||||
@ -3159,8 +3167,8 @@ DQN_FILE_SCOPE bool DqnMemStack::InitWithFixedMem(u8 *const mem, const size_t me
|
||||
return true;
|
||||
}
|
||||
|
||||
DQN_FILE_SCOPE bool DqnMemStack::InitWithFixedSize(size_t size, const bool zeroClear,
|
||||
const u32 byteAlign_, const DqnMemAPI memAPI_)
|
||||
DQN_FILE_SCOPE bool DqnMemStack::InitWithFixedSize(size_t size, bool const zeroClear,
|
||||
u32 const byteAlign_, DqnMemAPI const memAPI_)
|
||||
{
|
||||
bool result = this->Init(size, zeroClear, byteAlign_, memAPI_);
|
||||
if (result)
|
||||
@ -3173,7 +3181,7 @@ DQN_FILE_SCOPE bool DqnMemStack::InitWithFixedSize(size_t size, const bool zeroC
|
||||
return false;
|
||||
}
|
||||
|
||||
DQN_FILE_SCOPE bool DqnMemStack::Init(size_t size, const bool zeroClear, const u32 byteAlign_, const DqnMemAPI memAPI_)
|
||||
DQN_FILE_SCOPE bool DqnMemStack::Init(size_t size, bool const zeroClear, u32 const byteAlign_, DqnMemAPI const memAPI_)
|
||||
{
|
||||
if (!this || size < 0) return false;
|
||||
if (!DQN_ASSERT_MSG(!this->block, "MemStack has pre-existing block already attached"))
|
||||
@ -3331,7 +3339,7 @@ DQN_FILE_SCOPE bool DqnMemStack::FreeLastBlock()
|
||||
return result;
|
||||
}
|
||||
|
||||
DQN_FILE_SCOPE void DqnMemStack::ClearCurrBlock(const bool zeroClear)
|
||||
DQN_FILE_SCOPE void DqnMemStack::ClearCurrBlock(bool const zeroClear)
|
||||
{
|
||||
if (this->block)
|
||||
{
|
||||
@ -3396,7 +3404,7 @@ DqnMemStackTempRegionGuard::~DqnMemStackTempRegionGuard()
|
||||
// #DqnMemStack Advanced API Implementation
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
DQN_FILE_SCOPE DqnMemStack::Block *DqnMemStack::AllocateCompatibleBlock(size_t size,
|
||||
const bool zeroClear)
|
||||
bool const zeroClear)
|
||||
{
|
||||
if (this->flags & DqnMemStack::Flag::IsFixedMemoryFromUser) return nullptr;
|
||||
if (this->flags & DqnMemStack::Flag::IsNotExpandable) return nullptr;
|
||||
|
@ -1422,6 +1422,25 @@ void DqnArray_Test()
|
||||
|
||||
if (1)
|
||||
{
|
||||
if (1)
|
||||
{
|
||||
DqnArray<char> array1 = DqnArray_<char>(3);
|
||||
DQN_ASSERT(array1.count == 0);
|
||||
DQN_ASSERT(array1.max == 3);
|
||||
array1.Free();
|
||||
|
||||
array1 = DqnArray_<char>();
|
||||
DQN_ASSERT(array1.count == 0);
|
||||
DQN_ASSERT(array1.max == 0);
|
||||
|
||||
array1.Push('c');
|
||||
DQN_ASSERT(array1.count == 1);
|
||||
DQN_ASSERT(array1.max == 1);
|
||||
array1.Free();
|
||||
|
||||
LogSuccess("DqnArray(): Testing faux-array constructors DqnArray_()");
|
||||
}
|
||||
|
||||
if (1)
|
||||
{
|
||||
DqnArray<char> array = {};
|
||||
|
Loading…
Reference in New Issue
Block a user