Fix realloc bug destroying memory in stack

This commit is contained in:
Doyle Thai 2018-01-28 12:43:53 +11:00
parent 86d2db397c
commit 06b0f25f2a

55
dqn.h
View File

@ -478,8 +478,9 @@ public:
// API // API
// ============================================================================================= // =============================================================================================
// return: These functions return false if allocation failed. String is preserved. // return: These functions return false if allocation failed. String is preserved.
bool Expand (const i32 newMax); bool Expand (i32 newMax);
bool Sprintf (char const *const fmt, ...); bool Sprintf (char const *const fmt, ...);
bool VSprintf(char const *const fmt, va_list argList);
bool Append (DqnString const string); bool Append (DqnString const string);
bool Append (char const *const cstr, i32 bytesToCopy = -1); bool Append (char const *const cstr, i32 bytesToCopy = -1);
@ -493,6 +494,12 @@ public:
wchar_t *ToWChar(DqnMemAPI *const api = &DQN_DEFAULT_HEAP_ALLOCATOR); wchar_t *ToWChar(DqnMemAPI *const api = &DQN_DEFAULT_HEAP_ALLOCATOR);
}; };
class DqnSmartString : public DqnString
{
public:
~DqnSmartString() { this->Free(); }
};
DQN_FILE_SCOPE DqnString DqnString_(DqnMemAPI *const api = &DQN_DEFAULT_HEAP_ALLOCATOR); DQN_FILE_SCOPE DqnString DqnString_(DqnMemAPI *const api = &DQN_DEFAULT_HEAP_ALLOCATOR);
DQN_FILE_SCOPE DqnString DqnString_(DqnMemStack *const stack); DQN_FILE_SCOPE DqnString DqnString_(DqnMemStack *const stack);
@ -526,8 +533,9 @@ public:
bool InitSize (isize size_, DqnMemStack *const stack); bool InitSize (isize size_, DqnMemStack *const stack);
void Free (); void Free ();
bool Resize (isize newMax); bool Resize (isize newMax); // If (newMax < count), it will destroy the left over elements.
bool Grow (isize multiplier = 2); bool Grow (isize multiplier = 2);
T *Make (); // Get a ptr to the next free element in the array, increment count.
T *Push (T const *item, isize num); T *Push (T const *item, isize num);
T *Push (T const item); T *Push (T const item);
T *Insert (T const item, isize index); T *Insert (T const item, isize index);
@ -681,6 +689,24 @@ bool DqnArray<T>::Grow(isize multiplier)
return result; return result;
} }
template <typename T>
T *DqnArray<T>::Make()
{
bool accessible = true;
if (!this->data || this->count >= this->max)
{
accessible = this->Grow();
}
if (accessible)
{
T *result = this->data[this->count++];
return result;
}
return nullptr;
}
template <typename T> template <typename T>
T *DqnArray<T>::Push(T const *item, isize num) T *DqnArray<T>::Push(T const *item, isize num)
{ {
@ -2815,8 +2841,6 @@ DQN_FILE_SCOPE void DqnLog(char *file, char const *const functionName, i32 const
char userMsg[2048]; char userMsg[2048];
userMsg[0] = '\0'; userMsg[0] = '\0';
if (msg)
{
va_list argList; va_list argList;
va_start(argList, msg); va_start(argList, msg);
{ {
@ -2827,7 +2851,6 @@ DQN_FILE_SCOPE void DqnLog(char *file, char const *const functionName, i32 const
} }
} }
va_end(argList); va_end(argList);
}
char const *const formatStr = "DqnLog:%s:%s,%d: %s\n"; char const *const formatStr = "DqnLog:%s:%s,%d: %s\n";
fprintf(stderr, formatStr, file, functionName, lineNum, userMsg); fprintf(stderr, formatStr, file, functionName, lineNum, userMsg);
@ -2853,8 +2876,6 @@ DQN_FILE_SCOPE void DqnLog(char *file, char const *const functionName, i32 const
char userMsg[2048]; char userMsg[2048];
userMsg[0] = '\0'; userMsg[0] = '\0';
if (msg)
{
va_list argList; va_list argList;
va_start(argList, msg); va_start(argList, msg);
{ {
@ -2865,7 +2886,6 @@ DQN_FILE_SCOPE void DqnLog(char *file, char const *const functionName, i32 const
} }
} }
va_end(argList); va_end(argList);
}
char const *const formatStr = "DqnLog:%s:%s,%d(%s): %s\n"; char const *const formatStr = "DqnLog:%s:%s,%d(%s): %s\n";
fprintf(stderr, formatStr, file, functionName, lineNum, expr, userMsg); fprintf(stderr, formatStr, file, functionName, lineNum, expr, userMsg);
@ -3084,7 +3104,7 @@ FILE_SCOPE u8 *DqnMemAPIInternal_StackAllocatorCallback(DqnMemAPI *api, DqnMemAP
u8 *checkPtr = currUsagePtr - DQN_ALIGN_POW_N(request->oldSize, stack->byteAlign); u8 *checkPtr = currUsagePtr - DQN_ALIGN_POW_N(request->oldSize, stack->byteAlign);
// Last allocation, can safely allocate the remainder space. // Last allocation, can safely allocate the remainder space.
if (checkPtr == (u8 *)request->oldMemPtr || request->oldMemPtr == block->memory) if (checkPtr == (u8 *)request->oldMemPtr)
{ {
size_t remainingBytesToAlloc = request->newRequestSize - request->oldSize; size_t remainingBytesToAlloc = request->newRequestSize - request->oldSize;
DQN_ASSERT(remainingBytesToAlloc > 0); DQN_ASSERT(remainingBytesToAlloc > 0);
@ -5612,7 +5632,7 @@ bool DqnString::InitLiteralNoAlloc(char *const cstr, i32 cstrLen)
return true; return true;
} }
bool DqnString::Expand(const i32 newMax) bool DqnString::Expand(i32 newMax)
{ {
if (newMax < this->max) if (newMax < this->max)
{ {
@ -5696,6 +5716,16 @@ DQN_FILE_SCOPE bool DqnStringInternal_Append(DqnString *const str, char const *c
} }
bool DqnString::Sprintf(char const *fmt, ...) bool DqnString::Sprintf(char const *fmt, ...)
{
va_list argList;
va_start(argList, fmt);
bool result = this->VSprintf(fmt, argList);
va_end(argList);
return result;
}
bool DqnString::VSprintf(char const *fmt, va_list argList)
{ {
LOCAL_PERSIST char tmp[STB_SPRINTF_MIN]; LOCAL_PERSIST char tmp[STB_SPRINTF_MIN];
@ -5705,9 +5735,6 @@ bool DqnString::Sprintf(char const *fmt, ...)
return buf; return buf;
}; };
va_list argList;
va_start(argList, fmt);
{
i32 const reqLen = Dqn_vsprintfcb(PrintCallback, nullptr, tmp, fmt, argList); i32 const reqLen = Dqn_vsprintfcb(PrintCallback, nullptr, tmp, fmt, argList);
auto const remainingSpace = this->max - this->len; auto const remainingSpace = this->max - this->len;
if (reqLen > remainingSpace) if (reqLen > remainingSpace)
@ -5723,8 +5750,6 @@ bool DqnString::Sprintf(char const *fmt, ...)
i32 numCopied = Dqn_vsprintf(bufStart, fmt, argList); i32 numCopied = Dqn_vsprintf(bufStart, fmt, argList);
this->len += numCopied; this->len += numCopied;
DQN_ASSERT(this->len <= this->max); DQN_ASSERT(this->len <= this->max);
}
va_end(argList);
return true; return true;
} }