1
0
mirror of https://github.com/alliedmodders/hl2sdk.git synced 2025-09-19 12:06:07 +08:00

Force KeyValues to use g_pMemAlloc where applicable for string alloc.

This commit is contained in:
Nicholas Hastings
2015-07-12 17:56:24 -04:00
parent 14cc5ba738
commit 8bbf8148ef
4 changed files with 106 additions and 331 deletions

Binary file not shown.

View File

@ -14,17 +14,17 @@
#pragma once #pragma once
#endif #endif
// These memory debugging switches aren't relevant under Linux builds since memoverride.cpp #if !defined( NO_MALLOC_OVERRIDE ) && defined( POSIX )
// isn't built into Linux projects #define NO_MALLOC_OVERRIDE
#endif
#if defined( NO_MALLOC_OVERRIDE ) && !defined( NO_HOOK_MALLOC )
#define NO_HOOK_MALLOC
#endif
#ifndef POSIX #ifndef POSIX
// Define this in release to get memory tracking even in release builds // Define this in release to get memory tracking even in release builds
//#define USE_MEM_DEBUG 1 //#define USE_MEM_DEBUG 1
// Define this in release to get light memory debugging
//#define USE_LIGHT_MEM_DEBUG
// Define this to require -uselmd to turn light memory debugging on
//#define LIGHT_MEM_DEBUG_REQUIRES_CMD_LINE_SWITCH
#endif #endif
#if defined( _MEMTEST ) #if defined( _MEMTEST )
@ -57,18 +57,15 @@ typedef size_t (*MemAllocFailHandler_t)( size_t );
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
abstract_class IMemAlloc abstract_class IMemAlloc
{ {
private: public:
// Release versions // Release versions
virtual void *Alloc( size_t nSize ) = 0; virtual void *Alloc( size_t nSize ) = 0;
public:
virtual void *Realloc( void *pMem, size_t nSize ) = 0; virtual void *Realloc( void *pMem, size_t nSize ) = 0;
virtual void Free( void *pMem ) = 0; virtual void Free( void *pMem ) = 0;
virtual void *Expand_NoLongerSupported( void *pMem, size_t nSize ) = 0; virtual void *Expand_NoLongerSupported( void *pMem, size_t nSize ) = 0;
// Debug versions // Debug versions
virtual void *Alloc( size_t nSize, const char *pFileName, int nLine ) = 0; virtual void *Alloc( size_t nSize, const char *pFileName, int nLine ) = 0;
public:
virtual void *Realloc( void *pMem, size_t nSize, const char *pFileName, int nLine ) = 0; virtual void *Realloc( void *pMem, size_t nSize, const char *pFileName, int nLine ) = 0;
virtual void Free( void *pMem, const char *pFileName, int nLine ) = 0; virtual void Free( void *pMem, const char *pFileName, int nLine ) = 0;
virtual void *Expand_NoLongerSupported( void *pMem, size_t nSize, const char *pFileName, int nLine ) = 0; virtual void *Expand_NoLongerSupported( void *pMem, size_t nSize, const char *pFileName, int nLine ) = 0;
@ -125,8 +122,7 @@ public:
virtual void SetStatsExtraInfo( const char *pMapName, const char *pComment ) = 0; virtual void SetStatsExtraInfo( const char *pMapName, const char *pComment ) = 0;
#endif #endif
// Returns 0 if no failure, otherwise the size_t of the last requested chunk. // Returns 0 if no failure, otherwise the size_t of the last requested chunk
// "I'm sure this is completely thread safe!" Brian Deen 7/19/2012.
virtual size_t MemoryAllocFailed() = 0; virtual size_t MemoryAllocFailed() = 0;
virtual void CompactIncremental() = 0; virtual void CompactIncremental() = 0;
@ -156,7 +152,6 @@ inline void *MemAlloc_Alloc( size_t nSize )
{ {
return g_pMemAlloc->RegionAlloc( MEMALLOC_REGION, nSize ); return g_pMemAlloc->RegionAlloc( MEMALLOC_REGION, nSize );
} }
inline void *MemAlloc_Alloc( size_t nSize, const char *pFileName, int nLine ) inline void *MemAlloc_Alloc( size_t nSize, const char *pFileName, int nLine )
{ {
return g_pMemAlloc->RegionAlloc( MEMALLOC_REGION, nSize, pFileName, nLine ); return g_pMemAlloc->RegionAlloc( MEMALLOC_REGION, nSize, pFileName, nLine );
@ -165,12 +160,11 @@ inline void *MemAlloc_Alloc( size_t nSize, const char *pFileName, int nLine )
#undef MEMALLOC_REGION #undef MEMALLOC_REGION
inline void *MemAlloc_Alloc( size_t nSize ) inline void *MemAlloc_Alloc( size_t nSize )
{ {
return g_pMemAlloc->IndirectAlloc( nSize ); return g_pMemAlloc->Alloc( nSize );
} }
inline void *MemAlloc_Alloc( size_t nSize, const char *pFileName, int nLine ) inline void *MemAlloc_Alloc( size_t nSize, const char *pFileName, int nLine )
{ {
return g_pMemAlloc->IndirectAlloc( nSize, pFileName, nLine ); return g_pMemAlloc->Alloc( nSize, pFileName, nLine );
} }
#endif #endif
inline void MemAlloc_Free( void *ptr ) inline void MemAlloc_Free( void *ptr )
@ -181,25 +175,16 @@ inline void MemAlloc_Free( void *ptr, const char *pFileName, int nLine )
{ {
g_pMemAlloc->Free( ptr, pFileName, nLine ); g_pMemAlloc->Free( ptr, pFileName, nLine );
} }
//-----------------------------------------------------------------------------
inline bool ValueIsPowerOfTwo( size_t value ) // don't clash with mathlib definition
{
return (value & ( value - 1 )) == 0;
}
inline void *MemAlloc_AllocAligned( size_t size, size_t align ) inline void *MemAlloc_AllocAligned( size_t size, size_t align )
{ {
unsigned char *pAlloc, *pResult; unsigned char *pAlloc, *pResult;
if (!IsPowerOfTwo(align)) if (!IsPowerOfTwo(uint(align)))
return NULL; return NULL;
align = (align > sizeof(void *) ? align : sizeof(void *)) - 1; align = (align > sizeof(void *) ? align : sizeof(void *)) - 1;
if ( (pAlloc = (unsigned char*)g_pMemAlloc->IndirectAlloc( sizeof(void *) + align + size ) ) == (unsigned char*)NULL) if ( (pAlloc = (unsigned char*)g_pMemAlloc->Alloc( sizeof(void *) + align + size ) ) == (unsigned char*)NULL)
return NULL; return NULL;
pResult = (unsigned char*)( (size_t)(pAlloc + sizeof(void *) + align ) & ~align ); pResult = (unsigned char*)( (size_t)(pAlloc + sizeof(void *) + align ) & ~align );
@ -212,48 +197,12 @@ inline void *MemAlloc_AllocAligned( size_t size, size_t align, const char *pszFi
{ {
unsigned char *pAlloc, *pResult; unsigned char *pAlloc, *pResult;
if (!IsPowerOfTwo(align)) if (!IsPowerOfTwo(uint(align)))
return NULL; return NULL;
align = (align > sizeof(void *) ? align : sizeof(void *)) - 1; align = (align > sizeof(void *) ? align : sizeof(void *)) - 1;
if ( (pAlloc = (unsigned char*)g_pMemAlloc->IndirectAlloc( sizeof(void *) + align + size, pszFile, nLine ) ) == (unsigned char*)NULL) if ( (pAlloc = (unsigned char*)g_pMemAlloc->Alloc( sizeof(void *) + align + size, pszFile, nLine ) ) == (unsigned char*)NULL)
return NULL;
pResult = (unsigned char*)( (size_t)(pAlloc + sizeof(void *) + align ) & ~align );
((unsigned char**)(pResult))[-1] = pAlloc;
return (void *)pResult;
}
inline void *MemAlloc_AllocAlignedUnattributed( size_t size, size_t align )
{
unsigned char *pAlloc, *pResult;
if (!ValueIsPowerOfTwo(align))
return NULL;
align = (align > sizeof(void *) ? align : sizeof(void *)) - 1;
if ( (pAlloc = (unsigned char*)MemAlloc_Alloc( sizeof(void *) + align + size ) ) == (unsigned char*)NULL)
return NULL;
pResult = (unsigned char*)( (size_t)(pAlloc + sizeof(void *) + align ) & ~align );
((unsigned char**)(pResult))[-1] = pAlloc;
return (void *)pResult;
}
inline void *MemAlloc_AllocAlignedFileLine( size_t size, size_t align, const char *pszFile, int nLine )
{
unsigned char *pAlloc, *pResult;
if (!ValueIsPowerOfTwo(align))
return NULL;
align = (align > sizeof(void *) ? align : sizeof(void *)) - 1;
if ( (pAlloc = (unsigned char*)MemAlloc_Alloc( sizeof(void *) + align + size, pszFile, nLine ) ) == (unsigned char*)NULL)
return NULL; return NULL;
pResult = (unsigned char*)( (size_t)(pAlloc + sizeof(void *) + align ) & ~align ); pResult = (unsigned char*)( (size_t)(pAlloc + sizeof(void *) + align ) & ~align );
@ -264,7 +213,7 @@ inline void *MemAlloc_AllocAlignedFileLine( size_t size, size_t align, const cha
inline void *MemAlloc_ReallocAligned( void *ptr, size_t size, size_t align ) inline void *MemAlloc_ReallocAligned( void *ptr, size_t size, size_t align )
{ {
if ( !ValueIsPowerOfTwo( align ) ) if ( !IsPowerOfTwo( uint(align) ) )
return NULL; return NULL;
// Don't change alignment between allocation + reallocation. // Don't change alignment between allocation + reallocation.
@ -310,23 +259,6 @@ inline void MemAlloc_FreeAligned( void *pMemBlock )
g_pMemAlloc->Free( pAlloc ); g_pMemAlloc->Free( pAlloc );
} }
inline void MemAlloc_FreeAligned( void *pMemBlock, const char *pszFile, int nLine )
{
void *pAlloc;
if ( pMemBlock == NULL )
return;
pAlloc = pMemBlock;
// pAlloc points to the pointer to starting of the memory block
pAlloc = (void *)(((size_t)pAlloc & ~( sizeof(void *) - 1 ) ) - sizeof(void *));
// pAlloc is the pointer to the start of memory block
pAlloc = *( (void **)pAlloc );
g_pMemAlloc->Free( pAlloc, pszFile, nLine );
}
inline size_t MemAlloc_GetSizeAligned( void *pMemBlock ) inline size_t MemAlloc_GetSizeAligned( void *pMemBlock )
{ {
void *pAlloc; void *pAlloc;
@ -347,37 +279,19 @@ inline size_t MemAlloc_GetSizeAligned( void *pMemBlock )
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#if (defined(_DEBUG) || defined(USE_MEM_DEBUG)) #if (defined(_DEBUG) || defined(USE_MEM_DEBUG))
#define MEM_ALLOC_CREDIT_(tag) CMemAllocAttributeAlloction memAllocAttributeAlloction( tag, __LINE__ ) #define MEM_ALLOC_CREDIT_(tag) CMemAllocAttributeAlloction memAllocAttributeAlloction( tag, __LINE__ )
#define MemAlloc_PushAllocDbgInfo( pszFile, line ) g_pMemAlloc->PushAllocDbgInfo( pszFile, line ) #define MemAlloc_PushAllocDbgInfo( pszFile, line ) g_pMemAlloc->PushAllocDbgInfo( pszFile, line )
#define MemAlloc_PopAllocDbgInfo() g_pMemAlloc->PopAllocDbgInfo() #define MemAlloc_PopAllocDbgInfo() g_pMemAlloc->PopAllocDbgInfo()
#define MemAlloc_RegisterAllocation( pFileName, nLine, nLogicalSize, nActualSize, nTime ) g_pMemAlloc->RegisterAllocation( pFileName, nLine, nLogicalSize, nActualSize, nTime ) #define MemAlloc_RegisterAllocation( pFileName, nLine, nLogicalSize, nActualSize, nTime ) g_pMemAlloc->RegisterAllocation( pFileName, nLine, nLogicalSize, nActualSize, nTime )
#define MemAlloc_RegisterDeallocation( pFileName, nLine, nLogicalSize, nActualSize, nTime ) g_pMemAlloc->RegisterDeallocation( pFileName, nLine, nLogicalSize, nActualSize, nTime ) #define MemAlloc_RegisterDeallocation( pFileName, nLine, nLogicalSize, nActualSize, nTime ) g_pMemAlloc->RegisterDeallocation( pFileName, nLine, nLogicalSize, nActualSize, nTime )
#else #else
#define MEM_ALLOC_CREDIT_(tag) ((void)0) #define MEM_ALLOC_CREDIT_(tag) ((void)0)
#define MemAlloc_PushAllocDbgInfo( pszFile, line ) ((void)0) #define MemAlloc_PushAllocDbgInfo( pszFile, line ) ((void)0)
#define MemAlloc_PopAllocDbgInfo() ((void)0) #define MemAlloc_PopAllocDbgInfo() ((void)0)
#define MemAlloc_RegisterAllocation( pFileName, nLine, nLogicalSize, nActualSize, nTime ) ((void)0) #define MemAlloc_RegisterAllocation( pFileName, nLine, nLogicalSize, nActualSize, nTime ) ((void)0)
#define MemAlloc_RegisterDeallocation( pFileName, nLine, nLogicalSize, nActualSize, nTime ) ((void)0) #define MemAlloc_RegisterDeallocation( pFileName, nLine, nLogicalSize, nActualSize, nTime ) ((void)0)
#endif #endif
#define MemAlloc_DumpStats() g_pMemAlloc->DumpStats()
#define MemAlloc_CompactHeap() g_pMemAlloc->CompactHeap()
#define MemAlloc_OutOfMemory() g_pMemAlloc->OutOfMemory()
#define MemAlloc_CompactIncremental() g_pMemAlloc->CompactIncremental()
#define MemAlloc_DumpStatsFileBase( _filename ) g_pMemAlloc->DumpStatsFileBase( _filename )
#define MemAlloc_CrtCheckMemory() g_pMemAlloc->CrtCheckMemory()
#define MemAlloc_GlobalMemoryStatus( _usedMemory, _freeMemory ) g_pMemAlloc->GlobalMemoryStatus( _usedMemory, _freeMemory )
#define MemAlloc_MemoryAllocFailed() g_pMemAlloc->MemoryAllocFailed()
#define MemAlloc_GetDebugInfoSize() g_pMemAlloc->GetDebugInfoSize()
#define MemAlloc_SaveDebugInfo( pvDebugInfo ) g_pMemAlloc->SaveDebugInfo( pvDebugInfo )
#define MemAlloc_RestoreDebugInfo( pvDebugInfo ) g_pMemAlloc->RestoreDebugInfo( pvDebugInfo )
#define MemAlloc_InitDebugInfo( pvDebugInfo, pchRootFileName, nLine ) g_pMemAlloc->InitDebugInfo( pvDebugInfo, pchRootFileName, nLine )
#define MemAlloc_GetSize( x ) g_pMemAlloc->GetSize( x );
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
class CMemAllocAttributeAlloction class CMemAllocAttributeAlloction
@ -398,7 +312,7 @@ public:
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#if defined(MSVC) && ( defined(_DEBUG) || defined(USE_MEM_DEBUG) ) #if defined(_WIN32) && ( defined(_DEBUG) || defined(USE_MEM_DEBUG) )
#pragma warning(disable:4290) #pragma warning(disable:4290)
#pragma warning(push) #pragma warning(push)
@ -408,14 +322,7 @@ public:
// Note: typeid().name() is not threadsafe, so if the project needs to access it in multiple threads // Note: typeid().name() is not threadsafe, so if the project needs to access it in multiple threads
// simultaneously, it'll need a mutex. // simultaneously, it'll need a mutex.
#if defined(_CPPRTTI) && defined(MEM_DEBUG_CLASSNAME) #if defined(_CPPRTTI) && defined(MEM_DEBUG_CLASSNAME)
#define MEM_ALLOC_CREDIT_CLASS() MEM_ALLOC_CREDIT_( typeid(*this).name() )
template <typename T> const char *MemAllocClassName( T *p )
{
static const char *pszName = typeid(*p).name(); // @TODO: support having debug heap ignore certain allocations, and ignore memory allocated here [5/7/2009 tom]
return pszName;
}
#define MEM_ALLOC_CREDIT_CLASS() MEM_ALLOC_CREDIT_( MemAllocClassName( this ) )
#define MEM_ALLOC_CLASSNAME(type) (typeid((type*)(0)).name()) #define MEM_ALLOC_CLASSNAME(type) (typeid((type*)(0)).name())
#else #else
#define MEM_ALLOC_CREDIT_CLASS() MEM_ALLOC_CREDIT_( __FILE__ ) #define MEM_ALLOC_CREDIT_CLASS() MEM_ALLOC_CREDIT_( __FILE__ )
@ -446,13 +353,8 @@ struct MemAllocFileLine_t
}; };
#define MEMALLOC_DEFINE_EXTERNAL_TRACKING( tag ) \ #define MEMALLOC_DEFINE_EXTERNAL_TRACKING( tag ) \
static CUtlMap<void *, MemAllocFileLine_t, int> s_##tag##Allocs( DefLessFunc( void *) ); \ static CUtlMap<void *, MemAllocFileLine_t, int> g_##tag##Allocs( DefLessFunc( void *) ); \
CUtlMap<void *, MemAllocFileLine_t, int> * g_p##tag##Allocs = &s_##tag##Allocs; \ static const char *g_psz##tag##Alloc = strcpy( (char *)g_pMemAlloc->Alloc( strlen( #tag "Alloc" ) + 1, "intentional leak", 0 ), #tag "Alloc" );
const char * g_psz##tag##Alloc = strcpy( (char *)MemAlloc_Alloc( strlen( #tag "Alloc" ) + 1, "intentional leak", 0 ), #tag "Alloc" );
#define MEMALLOC_DECLARE_EXTERNAL_TRACKING( tag ) \
extern CUtlMap<void *, MemAllocFileLine_t, int> * g_p##tag##Allocs; \
extern const char * g_psz##tag##Alloc;
#define MemAlloc_RegisterExternalAllocation( tag, p, size ) \ #define MemAlloc_RegisterExternalAllocation( tag, p, size ) \
if ( !p ) \ if ( !p ) \
@ -463,7 +365,7 @@ struct MemAllocFileLine_t
g_pMemAlloc->GetActualDbgInfo( fileLine.pszFile, fileLine.line ); \ g_pMemAlloc->GetActualDbgInfo( fileLine.pszFile, fileLine.line ); \
if ( fileLine.pszFile != g_psz##tag##Alloc ) \ if ( fileLine.pszFile != g_psz##tag##Alloc ) \
{ \ { \
g_p##tag##Allocs->Insert( p, fileLine ); \ g_##tag##Allocs.Insert( p, fileLine ); \
} \ } \
\ \
MemAlloc_RegisterAllocation( fileLine.pszFile, fileLine.line, size, size, 0); \ MemAlloc_RegisterAllocation( fileLine.pszFile, fileLine.line, size, size, 0); \
@ -475,11 +377,11 @@ struct MemAllocFileLine_t
else \ else \
{ \ { \
MemAllocFileLine_t fileLine = { g_psz##tag##Alloc, 0 }; \ MemAllocFileLine_t fileLine = { g_psz##tag##Alloc, 0 }; \
CUtlMap<void *, MemAllocFileLine_t, int>::IndexType_t iRecordedFileLine = g_p##tag##Allocs->Find( p ); \ CUtlMap<void *, MemAllocFileLine_t, int>::IndexType_t iRecordedFileLine = g_##tag##Allocs.Find( p ); \
if ( iRecordedFileLine != g_p##tag##Allocs->InvalidIndex() ) \ if ( iRecordedFileLine != g_##tag##Allocs.InvalidIndex() ) \
{ \ { \
fileLine = (*g_p##tag##Allocs)[iRecordedFileLine]; \ fileLine = g_##tag##Allocs[iRecordedFileLine]; \
g_p##tag##Allocs->RemoveAt( iRecordedFileLine ); \ g_##tag##Allocs.RemoveAt( iRecordedFileLine ); \
} \ } \
\ \
MemAlloc_RegisterDeallocation( fileLine.pszFile, fileLine.line, size, size, 0); \ MemAlloc_RegisterDeallocation( fileLine.pszFile, fileLine.line, size, size, 0); \
@ -488,7 +390,6 @@ struct MemAllocFileLine_t
#else #else
#define MEMALLOC_DEFINE_EXTERNAL_TRACKING( tag ) #define MEMALLOC_DEFINE_EXTERNAL_TRACKING( tag )
#define MEMALLOC_DECLARE_EXTERNAL_TRACKING( tag )
#define MemAlloc_RegisterExternalAllocation( tag, p, size ) ((void)0) #define MemAlloc_RegisterExternalAllocation( tag, p, size ) ((void)0)
#define MemAlloc_RegisterExternalDeallocation( tag, p, size ) ((void)0) #define MemAlloc_RegisterExternalDeallocation( tag, p, size ) ((void)0)
@ -499,7 +400,7 @@ struct MemAllocFileLine_t
#elif defined( POSIX ) #elif defined( POSIX )
#if defined( OSX ) #if defined( OSX )
// Mac always aligns allocs, don't need to call posix_memalign // Mac always aligns allocs, don't need to call posix_memalign which doesn't exist in 10.5.8 which TF2 still needs to run on
//inline void *memalign(size_t alignment, size_t size) {void *pTmp=NULL; posix_memalign(&pTmp, alignment, size); return pTmp;} //inline void *memalign(size_t alignment, size_t size) {void *pTmp=NULL; posix_memalign(&pTmp, alignment, size); return pTmp;}
inline void *memalign(size_t alignment, size_t size) {void *pTmp=NULL; pTmp = malloc(size); return pTmp;} inline void *memalign(size_t alignment, size_t size) {void *pTmp=NULL; pTmp = malloc(size); return pTmp;}
#endif #endif
@ -535,12 +436,6 @@ inline void *MemAlloc_ReallocAligned( void *ptr, size_t size, size_t align )
return ptr_new_aligned; return ptr_new_aligned;
} }
#else
#define MemAlloc_GetDebugInfoSize() g_pMemAlloc->GetDebugInfoSize()
#define MemAlloc_SaveDebugInfo( pvDebugInfo ) g_pMemAlloc->SaveDebugInfo( pvDebugInfo )
#define MemAlloc_RestoreDebugInfo( pvDebugInfo ) g_pMemAlloc->RestoreDebugInfo( pvDebugInfo )
#define MemAlloc_InitDebugInfo( pvDebugInfo, pchRootFileName, nLine ) g_pMemAlloc->InitDebugInfo( pvDebugInfo, pchRootFileName, nLine )
#endif // !STEAM && !NO_MALLOC_OVERRIDE #endif // !STEAM && !NO_MALLOC_OVERRIDE
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -555,122 +450,9 @@ inline void *MemAlloc_ReallocAligned( void *ptr, size_t size, size_t align )
#define MemAlloc_PushAllocDbgInfo( pszFile, line ) #define MemAlloc_PushAllocDbgInfo( pszFile, line )
#define MemAlloc_PopAllocDbgInfo() #define MemAlloc_PopAllocDbgInfo()
#define MemAlloc_RegisterAllocation( pFileName, nLine, nLogicalSize, nActualSize, nTime ) ((void)0)
#define MemAlloc_RegisterDeallocation( pFileName, nLine, nLogicalSize, nActualSize, nTime ) ((void)0)
#define MemAlloc_DumpStats() ((void)0)
#define MemAlloc_CompactHeap() ((void)0)
#define MemAlloc_OutOfMemory() ((void)0)
#define MemAlloc_CompactIncremental() ((void)0)
#define MemAlloc_DumpStatsFileBase( _filename ) ((void)0)
inline bool MemAlloc_CrtCheckMemory() { return true; }
inline void MemAlloc_GlobalMemoryStatus( size_t *pusedMemory, size_t *pfreeMemory )
{
*pusedMemory = 0;
*pfreeMemory = 0;
}
#define MemAlloc_MemoryAllocFailed() 0
#define MemAlloc_GetDebugInfoSize() 0
#define MemAlloc_SaveDebugInfo( pvDebugInfo ) ((void)0)
#define MemAlloc_RestoreDebugInfo( pvDebugInfo ) ((void)0)
#define MemAlloc_InitDebugInfo( pvDebugInfo, pchRootFileName, nLine ) ((void)0)
#define MEMALLOC_DEFINE_EXTERNAL_TRACKING( tag ) #define MEMALLOC_DEFINE_EXTERNAL_TRACKING( tag )
#define MemAlloc_RegisterExternalAllocation( tag, p, size ) ((void)0)
#define MemAlloc_RegisterExternalDeallocation( tag, p, size ) ((void)0)
#endif // !STEAM && NO_MALLOC_OVERRIDE #endif // !STEAM && NO_MALLOC_OVERRIDE
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// linux memory tracking via hooks.
#if defined( POSIX ) && !defined( NO_HOOK_MALLOC )
PLATFORM_INTERFACE void MemoryLogMessage( char const *s ); // throw a message into the memory log
PLATFORM_INTERFACE void EnableMemoryLogging( bool bOnOff );
PLATFORM_INTERFACE void DumpMemoryLog( int nThresh );
PLATFORM_INTERFACE void DumpMemorySummary( void );
PLATFORM_INTERFACE void SetMemoryMark( void );
PLATFORM_INTERFACE void DumpChangedMemory( int nThresh );
#else
FORCEINLINE void MemoryLogMessage( char const *s )
{
}
FORCEINLINE void EnableMemoryLogging( bool bOnOff )
{
}
FORCEINLINE void DumpMemoryLog( int nThresh )
{
}
FORCEINLINE void DumpMemorySummary( void )
{
}
FORCEINLINE void SetMemoryMark( void )
{
}
FORCEINLINE void DumpChangedMemory( int nThresh )
{
}
#endif
#ifdef POSIX
// ApproximateProcessMemoryUsage returns the approximate memory footprint of this process.
PLATFORM_INTERFACE size_t ApproximateProcessMemoryUsage( void );
#else
FORCEINLINE size_t ApproximateProcessMemoryUsage( void )
{
return 0;
}
#endif
struct aligned_tmp_t
{
// empty base class
};
// template here to allow adding alignment at levels of hierarchy that aren't the base
template< int bytesAlignment = 16, class T = aligned_tmp_t >
class CAlignedNewDelete : public T
{
public:
/*
Note that this class does not overload operator new[] and delete[] which means that
classes that depend on this for alignment may end up misaligned if an array is
allocated. This problem is now mostly theoretical because this class is mostly
obsolete.
*/
void *operator new( size_t nSize )
{
return MemAlloc_AllocAligned( nSize, bytesAlignment );
}
void* operator new( size_t nSize, int nBlockUse, const char *pFileName, int nLine )
{
return MemAlloc_AllocAlignedFileLine( nSize, bytesAlignment, pFileName, nLine );
}
void operator delete(void *pData)
{
if ( pData )
{
MemAlloc_FreeAligned( pData );
}
}
void operator delete( void* pData, int nBlockUse, const char *pFileName, int nLine )
{
if ( pData )
{
MemAlloc_FreeAligned( pData, pFileName, nLine );
}
}
};
#endif /* TIER0_MEMALLOC_H */ #endif /* TIER0_MEMALLOC_H */

View File

@ -11,6 +11,14 @@
// to include this potentially multiple times (since we can deactivate debugging // to include this potentially multiple times (since we can deactivate debugging
// by including memdbgoff.h) // by including memdbgoff.h)
#if !defined( NO_MALLOC_OVERRIDE ) && defined( POSIX )
#define NO_MALLOC_OVERRIDE
#endif
#if defined( NO_MALLOC_OVERRIDE ) && !defined( NO_HOOK_MALLOC )
#define NO_HOOK_MALLOC
#endif
#if !defined(STEAM) && !defined(NO_MALLOC_OVERRIDE) #if !defined(STEAM) && !defined(NO_MALLOC_OVERRIDE)
// SPECIAL NOTE #2: This must be the final include in a .cpp or .h file!!! // SPECIAL NOTE #2: This must be the final include in a .cpp or .h file!!!
@ -19,53 +27,47 @@
#define USE_MEM_DEBUG 1 #define USE_MEM_DEBUG 1
#endif #endif
#if defined(NO_HOOK_MALLOC)
#undef USE_MEM_DEBUG
#endif
// If debug build or ndebug and not already included MS custom alloc files, or already included this file // If debug build or ndebug and not already included MS custom alloc files, or already included this file
#if (defined(_DEBUG) || !defined(_INC_CRTDBG)) || defined(MEMDBGON_H) #if (defined(_DEBUG) || !defined(_INC_CRTDBG)) || defined(MEMDBGON_H)
#include "tier0/basetypes.h" #include "basetypes.h"
#ifdef _WIN32
#include "tier0/valve_off.h" #include <tchar.h>
#ifdef COMPILER_MSVC #else
#include <tchar.h> #include <wchar.h>
#else #endif
#include <wchar.h> #include <string.h>
#endif #if defined __APPLE__
#include <string.h> #include <stdlib.h>
#include <stdlib.h> #else
#include "tier0/valve_on.h" #include <malloc.h>
#endif
#include "commonmacros.h" #include "commonmacros.h"
#include "memalloc.h" #include "memalloc.h"
#ifdef _WIN32
#ifndef MEMALLOC_REGION
#define MEMALLOC_REGION 0
#endif
#else
#undef MEMALLOC_REGION
#endif
#if defined(USE_MEM_DEBUG) #if defined(USE_MEM_DEBUG)
#if defined(POSIX) #if defined(_LINUX) || defined(__APPLE__)
#define _NORMAL_BLOCK 1 #define _NORMAL_BLOCK 1
#include "tier0/valve_off.h"
#include <cstddef> #include <cstddef>
#include <glob.h> #include <glob.h>
#include <new> #include <new>
#include <sys/types.h> #include <sys/types.h>
#if !defined( DID_THE_OPERATOR_NEW ) #if !defined( DID_THE_OPERATOR_NEW )
#define DID_THE_OPERATOR_NEW #define DID_THE_OPERATOR_NEW
// posix doesn't have a new of this form, so we impl our own inline void* operator new( size_t nSize, int blah, const char *pFileName, int nLine )
void* operator new( size_t nSize, int blah, const char *pFileName, int nLine ); {
void* operator new[]( size_t nSize, int blah, const char *pFileName, int nLine ); return g_pMemAlloc->Alloc( nSize, pFileName, nLine );
}
inline void* operator new[]( size_t nSize, int blah, const char *pFileName, int nLine )
{
return g_pMemAlloc->Alloc( nSize, pFileName, nLine );
}
#endif #endif
#else // defined(POSIX) #else // defined(_LINUX)
// Include crtdbg.h and make sure _DEBUG is set to 1. // Include crtdbg.h and make sure _DEBUG is set to 1.
#if !defined(_DEBUG) #if !defined(_DEBUG)
@ -76,7 +78,7 @@
#include <crtdbg.h> #include <crtdbg.h>
#endif // !defined(_DEBUG) #endif // !defined(_DEBUG)
#endif // defined(POSIX) #endif // defined(_LINUX)
#endif #endif
#include "tier0/memdbgoff.h" #include "tier0/memdbgoff.h"
@ -103,30 +105,22 @@ inline void *MemAlloc_InlineCallocMemset( void *pMem, size_t nCount, size_t nEle
} }
#endif #endif
#define calloc(c, s) MemAlloc_InlineCallocMemset(malloc(c*s), c, s) #define calloc(c, s) MemAlloc_InlineCallocMemset(malloc(c*s), c, s)
#ifndef USE_LIGHT_MEM_DEBUG
#define free(p) g_pMemAlloc->Free( p ) #define free(p) g_pMemAlloc->Free( p )
#define _aligned_free( p ) MemAlloc_FreeAligned( p )
#else
extern const char *g_pszModule;
#define free(p) g_pMemAlloc->Free( p, g_pszModule, 0 )
#define _aligned_free( p ) MemAlloc_FreeAligned( p, g_pszModule, 0 )
#endif
#define _msize(p) g_pMemAlloc->GetSize( p ) #define _msize(p) g_pMemAlloc->GetSize( p )
#define _expand(p, s) _expand_NoLongerSupported(p, s) #define _expand(p, s) _expand_NoLongerSupported(p, s)
#define _aligned_free( p ) MemAlloc_FreeAligned( p )
// -------------------------------------------------------- // --------------------------------------------------------
// Debug path // Debug path
#if defined(USE_MEM_DEBUG) #if defined(USE_MEM_DEBUG)
#define malloc(s) MemAlloc_Alloc( s, __FILE__, __LINE__) #define malloc(s) g_pMemAlloc->Alloc( s, __FILE__, __LINE__)
#define realloc(p, s) g_pMemAlloc->Realloc( p, s, __FILE__, __LINE__ ) #define realloc(p, s) g_pMemAlloc->Realloc( p, s, __FILE__, __LINE__ )
#define _aligned_malloc( s, a ) MemAlloc_AllocAlignedFileLine( s, a, __FILE__, __LINE__ ) #define _aligned_malloc( s, a ) MemAlloc_AllocAligned( s, a, __FILE__, __LINE__ )
#define _malloc_dbg(s, t, f, l) WHYCALLINGTHISDIRECTLY(s) #define _malloc_dbg(s, t, f, l) WHYCALLINGTHISDIRECTLY(s)
#if !defined( GNUC )
#if defined(__AFX_H__) && defined(DEBUG_NEW) #if defined(__AFX_H__) && defined(DEBUG_NEW)
#define new DEBUG_NEW #define new DEBUG_NEW
#else #else
@ -134,7 +128,6 @@ extern const char *g_pszModule;
#define MEMALL_DEBUG_NEW new(_NORMAL_BLOCK, __FILE__, __LINE__) #define MEMALL_DEBUG_NEW new(_NORMAL_BLOCK, __FILE__, __LINE__)
#define new MEMALL_DEBUG_NEW #define new MEMALL_DEBUG_NEW
#endif #endif
#endif
#undef _strdup #undef _strdup
#undef strdup #undef strdup
@ -157,7 +150,7 @@ inline char *MemAlloc_StrDup(const char *pString, const char *pFileName, unsigne
return NULL; return NULL;
size_t len = strlen(pString) + 1; size_t len = strlen(pString) + 1;
if ((pMemory = (char *)MemAlloc_Alloc(len, pFileName, nLine)) != NULL) if ((pMemory = (char *)g_pMemAlloc->Alloc(len, pFileName, nLine)) != NULL)
{ {
return strcpy( pMemory, pString ); return strcpy( pMemory, pString );
} }
@ -173,7 +166,7 @@ inline wchar_t *MemAlloc_WcStrDup(const wchar_t *pString, const char *pFileName,
return NULL; return NULL;
size_t len = (wcslen(pString) + 1); size_t len = (wcslen(pString) + 1);
if ((pMemory = (wchar_t *)MemAlloc_Alloc(len * sizeof(wchar_t), pFileName, nLine)) != NULL) if ((pMemory = (wchar_t *)g_pMemAlloc->Alloc(len * sizeof(wchar_t), pFileName, nLine)) != NULL)
{ {
return wcscpy( pMemory, pString ); return wcscpy( pMemory, pString );
} }
@ -187,15 +180,9 @@ inline wchar_t *MemAlloc_WcStrDup(const wchar_t *pString, const char *pFileName,
// -------------------------------------------------------- // --------------------------------------------------------
// Release path // Release path
#ifndef USE_LIGHT_MEM_DEBUG #define malloc(s) g_pMemAlloc->Alloc( s )
#define malloc(s) MemAlloc_Alloc( s )
#define realloc(p, s) g_pMemAlloc->Realloc( p, s ) #define realloc(p, s) g_pMemAlloc->Realloc( p, s )
#define _aligned_malloc( s, a ) MemAlloc_AllocAligned( s, a ) #define _aligned_malloc( s, a ) MemAlloc_AllocAligned( s, a )
#else
#define malloc(s) MemAlloc_Alloc( s, g_pszModule, 0 )
#define realloc(p, s) g_pMemAlloc->Realloc( p, s, g_pszModule, 0 )
#define _aligned_malloc( s, a ) MemAlloc_AllocAlignedFileLine( s, a, g_pszModule, 0 )
#endif
#ifndef _malloc_dbg #ifndef _malloc_dbg
#define _malloc_dbg(s, t, f, l) WHYCALLINGTHISDIRECTLY(s) #define _malloc_dbg(s, t, f, l) WHYCALLINGTHISDIRECTLY(s)
@ -224,7 +211,7 @@ inline char *MemAlloc_StrDup(const char *pString)
return NULL; return NULL;
size_t len = strlen(pString) + 1; size_t len = strlen(pString) + 1;
if ((pMemory = (char *)malloc(len)) != NULL) if ((pMemory = (char *)g_pMemAlloc->Alloc(len)) != NULL)
{ {
return strcpy( pMemory, pString ); return strcpy( pMemory, pString );
} }
@ -240,7 +227,7 @@ inline wchar_t *MemAlloc_WcStrDup(const wchar_t *pString)
return NULL; return NULL;
size_t len = (wcslen(pString) + 1); size_t len = (wcslen(pString) + 1);
if ((pMemory = (wchar_t *)malloc(len * sizeof(wchar_t))) != NULL) if ((pMemory = (wchar_t *)g_pMemAlloc->Alloc(len * sizeof(wchar_t))) != NULL)
{ {
return wcscpy( pMemory, pString ); return wcscpy( pMemory, pString );
} }
@ -265,9 +252,4 @@ inline wchar_t *MemAlloc_WcStrDup(const wchar_t *pString)
#endif #endif
#endif // _INC_CRTDBG #endif // _INC_CRTDBG
#else
// Needed for MEM_ALLOC_CREDIT(), MemAlloc_Alloc(), etc.
#include "memalloc.h"
#endif // !STEAM && !NO_MALLOC_OVERRIDE #endif // !STEAM && !NO_MALLOC_OVERRIDE

View File

@ -27,6 +27,17 @@
// memdbgon must be the last include file in a .cpp file!!! // memdbgon must be the last include file in a .cpp file!!!
#include <tier0/memdbgon.h> #include <tier0/memdbgon.h>
template<typename T>
T *KVStringAlloc(size_t nLength)
{
return reinterpret_cast<T*>(MemAlloc_Alloc(sizeof(T) * nLength));
}
void KVStringDelete(void* pMem)
{
MemAlloc_Free(pMem);
}
static const char * s_LastFileLoadingFrom = "unknown"; // just needed for error messages static const char * s_LastFileLoadingFrom = "unknown"; // just needed for error messages
#define KEYVALUES_TOKEN_SIZE 1024 #define KEYVALUES_TOKEN_SIZE 1024
@ -323,9 +334,9 @@ void KeyValues::RemoveEverything()
delete dat; delete dat;
} }
delete [] m_sValue; KVStringDelete(m_sValue);
m_sValue = NULL; m_sValue = NULL;
delete [] m_wsValue; KVStringDelete(m_wsValue);
m_wsValue = NULL; m_wsValue = NULL;
} }
@ -1280,9 +1291,9 @@ void KeyValues::SetColor( const char *keyName, Color value)
void KeyValues::SetStringValue( char const *strValue ) void KeyValues::SetStringValue( char const *strValue )
{ {
// delete the old value // delete the old value
delete [] m_sValue; KVStringDelete(m_sValue);
// make sure we're not storing the WSTRING - as we're converting over to STRING // make sure we're not storing the WSTRING - as we're converting over to STRING
delete [] m_wsValue; KVStringDelete(m_wsValue);
m_wsValue = NULL; m_wsValue = NULL;
if (!strValue) if (!strValue)
@ -1293,7 +1304,7 @@ void KeyValues::SetStringValue( char const *strValue )
// allocate memory for the new value and copy it in // allocate memory for the new value and copy it in
int len = Q_strlen( strValue ); int len = Q_strlen( strValue );
m_sValue = new char[len + 1]; m_sValue = KVStringAlloc<char>(len + 1);
Q_memcpy( m_sValue, strValue, len+1 ); Q_memcpy( m_sValue, strValue, len+1 );
m_iDataType = TYPE_STRING; m_iDataType = TYPE_STRING;
@ -1309,9 +1320,9 @@ void KeyValues::SetString( const char *keyName, const char *value )
if ( dat ) if ( dat )
{ {
// delete the old value // delete the old value
delete [] dat->m_sValue; KVStringDelete(dat->m_sValue);
// make sure we're not storing the WSTRING - as we're converting over to STRING // make sure we're not storing the WSTRING - as we're converting over to STRING
delete [] dat->m_wsValue; KVStringDelete(dat->m_wsValue);
dat->m_wsValue = NULL; dat->m_wsValue = NULL;
if (!value) if (!value)
@ -1322,7 +1333,7 @@ void KeyValues::SetString( const char *keyName, const char *value )
// allocate memory for the new value and copy it in // allocate memory for the new value and copy it in
int len = Q_strlen( value ); int len = Q_strlen( value );
dat->m_sValue = new char[len + 1]; dat->m_sValue = KVStringAlloc<char>(len + 1);
Q_memcpy( dat->m_sValue, value, len+1 ); Q_memcpy( dat->m_sValue, value, len+1 );
dat->m_iDataType = TYPE_STRING; dat->m_iDataType = TYPE_STRING;
@ -1338,9 +1349,9 @@ void KeyValues::SetWString( const char *keyName, const wchar_t *value )
if ( dat ) if ( dat )
{ {
// delete the old value // delete the old value
delete [] dat->m_wsValue; KVStringDelete(dat->m_wsValue);
// make sure we're not storing the STRING - as we're converting over to WSTRING // make sure we're not storing the STRING - as we're converting over to WSTRING
delete [] dat->m_sValue; KVStringDelete(dat->m_sValue);
dat->m_sValue = NULL; dat->m_sValue = NULL;
if (!value) if (!value)
@ -1351,7 +1362,7 @@ void KeyValues::SetWString( const char *keyName, const wchar_t *value )
// allocate memory for the new value and copy it in // allocate memory for the new value and copy it in
int len = wcslen( value ); int len = wcslen( value );
dat->m_wsValue = new wchar_t[len + 1]; dat->m_wsValue = KVStringAlloc<wchar_t>(len + 1);
Q_memcpy( dat->m_wsValue, value, (len+1) * sizeof(wchar_t) ); Q_memcpy( dat->m_wsValue, value, (len+1) * sizeof(wchar_t) );
dat->m_iDataType = TYPE_WSTRING; dat->m_iDataType = TYPE_WSTRING;
@ -1382,12 +1393,12 @@ void KeyValues::SetUint64( const char *keyName, uint64 value )
if ( dat ) if ( dat )
{ {
// delete the old value // delete the old value
delete [] dat->m_sValue; KVStringDelete(dat->m_sValue);
// make sure we're not storing the WSTRING - as we're converting over to STRING // make sure we're not storing the WSTRING - as we're converting over to STRING
delete [] dat->m_wsValue; KVStringDelete(dat->m_wsValue);
dat->m_wsValue = NULL; dat->m_wsValue = NULL;
dat->m_sValue = new char[sizeof(uint64)]; dat->m_sValue = KVStringAlloc<char>(sizeof(uint64));
*((uint64 *)dat->m_sValue) = value; *((uint64 *)dat->m_sValue) = value;
dat->m_iDataType = TYPE_UINT64; dat->m_iDataType = TYPE_UINT64;
} }
@ -1444,7 +1455,7 @@ void KeyValues::RecursiveCopyKeyValues( KeyValues& src )
if( src.m_sValue ) if( src.m_sValue )
{ {
int len = Q_strlen(src.m_sValue) + 1; int len = Q_strlen(src.m_sValue) + 1;
m_sValue = new char[len]; m_sValue = KVStringAlloc<char>(len);
Q_strncpy( m_sValue, src.m_sValue, len ); Q_strncpy( m_sValue, src.m_sValue, len );
} }
break; break;
@ -1453,7 +1464,7 @@ void KeyValues::RecursiveCopyKeyValues( KeyValues& src )
m_iValue = src.m_iValue; m_iValue = src.m_iValue;
Q_snprintf( buf,sizeof(buf), "%d", m_iValue ); Q_snprintf( buf,sizeof(buf), "%d", m_iValue );
int len = Q_strlen(buf) + 1; int len = Q_strlen(buf) + 1;
m_sValue = new char[len]; m_sValue = KVStringAlloc<char>(len);
Q_strncpy( m_sValue, buf, len ); Q_strncpy( m_sValue, buf, len );
} }
break; break;
@ -1462,7 +1473,7 @@ void KeyValues::RecursiveCopyKeyValues( KeyValues& src )
m_flValue = src.m_flValue; m_flValue = src.m_flValue;
Q_snprintf( buf,sizeof(buf), "%f", m_flValue ); Q_snprintf( buf,sizeof(buf), "%f", m_flValue );
int len = Q_strlen(buf) + 1; int len = Q_strlen(buf) + 1;
m_sValue = new char[len]; m_sValue = KVStringAlloc<char>(len);
Q_strncpy( m_sValue, buf, len ); Q_strncpy( m_sValue, buf, len );
} }
break; break;
@ -1473,7 +1484,7 @@ void KeyValues::RecursiveCopyKeyValues( KeyValues& src )
break; break;
case TYPE_UINT64: case TYPE_UINT64:
{ {
m_sValue = new char[sizeof(uint64)]; m_sValue = KVStringAlloc<char>(sizeof(uint64));
Q_memcpy( m_sValue, src.m_sValue, sizeof(uint64) ); Q_memcpy( m_sValue, src.m_sValue, sizeof(uint64) );
} }
break; break;
@ -1584,7 +1595,7 @@ KeyValues *KeyValues::MakeCopy( void ) const
{ {
int len = Q_strlen( m_sValue ); int len = Q_strlen( m_sValue );
Assert( !newKeyValue->m_sValue ); Assert( !newKeyValue->m_sValue );
newKeyValue->m_sValue = new char[len + 1]; newKeyValue->m_sValue = KVStringAlloc<char>(len + 1);
Q_memcpy( newKeyValue->m_sValue, m_sValue, len+1 ); Q_memcpy( newKeyValue->m_sValue, m_sValue, len+1 );
} }
} }
@ -1594,7 +1605,7 @@ KeyValues *KeyValues::MakeCopy( void ) const
if ( m_wsValue ) if ( m_wsValue )
{ {
int len = wcslen( m_wsValue ); int len = wcslen( m_wsValue );
newKeyValue->m_wsValue = new wchar_t[len+1]; newKeyValue->m_wsValue = KVStringAlloc<wchar_t>(len + 1);
Q_memcpy( newKeyValue->m_wsValue, m_wsValue, (len+1)*sizeof(wchar_t)); Q_memcpy( newKeyValue->m_wsValue, m_wsValue, (len+1)*sizeof(wchar_t));
} }
} }
@ -1620,7 +1631,7 @@ KeyValues *KeyValues::MakeCopy( void ) const
break; break;
case TYPE_UINT64: case TYPE_UINT64:
newKeyValue->m_sValue = new char[sizeof(uint64)]; newKeyValue->m_sValue = KVStringAlloc<char>(sizeof(uint64));
Q_memcpy( newKeyValue->m_sValue, m_sValue, sizeof(uint64) ); Q_memcpy( newKeyValue->m_sValue, m_sValue, sizeof(uint64) );
break; break;
}; };
@ -2062,7 +2073,7 @@ void KeyValues::RecursiveLoadFromBuffer( char const *resourceName, CUtlBuffer &b
if (dat->m_sValue) if (dat->m_sValue)
{ {
delete[] dat->m_sValue; KVStringDelete(dat->m_sValue);
dat->m_sValue = NULL; dat->m_sValue = NULL;
} }
@ -2094,7 +2105,7 @@ void KeyValues::RecursiveLoadFromBuffer( char const *resourceName, CUtlBuffer &b
digit -= 'A' - ( '9' + 1 ); digit -= 'A' - ( '9' + 1 );
retVal = ( retVal * 16 ) + ( digit - '0' ); retVal = ( retVal * 16 ) + ( digit - '0' );
} }
dat->m_sValue = new char[sizeof(uint64)]; dat->m_sValue = KVStringAlloc<char>(sizeof(uint64));
*((uint64 *)dat->m_sValue) = retVal; *((uint64 *)dat->m_sValue) = retVal;
dat->m_iDataType = TYPE_UINT64; dat->m_iDataType = TYPE_UINT64;
} }
@ -2116,7 +2127,7 @@ void KeyValues::RecursiveLoadFromBuffer( char const *resourceName, CUtlBuffer &b
if (dat->m_iDataType == TYPE_STRING) if (dat->m_iDataType == TYPE_STRING)
{ {
// copy in the string information // copy in the string information
dat->m_sValue = new char[len+1]; dat->m_sValue = KVStringAlloc<char>(len + 1);
Q_memcpy( dat->m_sValue, value, len+1 ); Q_memcpy( dat->m_sValue, value, len+1 );
} }
@ -2274,7 +2285,7 @@ bool KeyValues::ReadAsBinary( CUtlBuffer &buffer )
token[KEYVALUES_TOKEN_SIZE-1] = 0; token[KEYVALUES_TOKEN_SIZE-1] = 0;
int len = Q_strlen( token ); int len = Q_strlen( token );
dat->m_sValue = new char[len + 1]; dat->m_sValue = KVStringAlloc<char>(len + 1);
Q_memcpy( dat->m_sValue, token, len+1 ); Q_memcpy( dat->m_sValue, token, len+1 );
break; break;
@ -2293,7 +2304,7 @@ bool KeyValues::ReadAsBinary( CUtlBuffer &buffer )
case TYPE_UINT64: case TYPE_UINT64:
{ {
dat->m_sValue = new char[sizeof(uint64)]; dat->m_sValue = KVStringAlloc<char>(sizeof(uint64));
*((double *)dat->m_sValue) = buffer.GetDouble(); *((double *)dat->m_sValue) = buffer.GetDouble();
} }