PathEngine home | previous: | next: |
The client application can create objects derived from this interface to specify custom memory allocation strategies or to generate memory allocation statistics.
Defined in SDKRoot/code/externalAPI/i_pathengine.h.
class iAllocator { public: virtual ~iAllocator() {} virtual void* allocate(uint32_t size) = 0; virtual void deallocate(void* ptr) = 0; virtual void* expand(void* oldPtr, uint32_t oldSize, uint32_t oldSize_Used, uint32_t newSize) = 0; }; |
Allocates memory according to the allocator objects allocation scheme. | ||
Frees memory previously allocated with allocate(). | ||
Expands a previously allocated memory block, either in place (with heap modification as in system realloc) or by allocating a new, larger block and copying data. |
A vanilla implementation of this interface, based on operator new and delete, is as follows:
#include "externalAPI/i_pathengine.h" #include <cassert> #include <cstring> class cOperatorNewAllocator : public iAllocator { public: void* allocate(uint32_t size) { assert(size); return operator new(static_cast<size_t>(size)); } void deallocate(void* ptr) { operator delete(ptr); } void* expand(void* oldPtr, uint32_t oldSize, uint32_t oldSize_Used, uint32_t newSize) { assert(oldPtr); assert(oldSize); assert(oldSize_Used <= oldSize); assert(newSize > oldSize); void* newPtr = allocate(newSize); memcpy(newPtr, oldPtr, static_cast<size_t>(oldSize_Used)); deallocate(oldPtr); return newPtr; } }; |
This implements buffer expansion in terms of re-allocation and copy, but the possibility to expand buffers in place can make some difference to performance for some preprocess build operations (in particular on Linux), and is worth supporting if possible.
An alternative vanilla implementation, that uses malloc, free and realloc (for expand in place) is then as follows:
#include "externalAPI/i_pathengine.h" #include <cassert> #include <stdlib.h> class cMallocAllocator : public iAllocator { public: void* allocate(uint32_t size) { assert(size); return malloc(static_cast<size_t>(size)); } void deallocate(void* ptr) { free(ptr); } void* expand(void* oldPtr, uint32_t oldSize, uint32_t oldSize_Used, uint32_t newSize) { assert(oldPtr); assert(oldSize); assert(oldSize_Used <= oldSize); assert(newSize > oldSize); return realloc(oldPtr, static_cast<size_t>(newSize)); } }; |
The following extends the operator new version to add checks that call counts to allocation and free match.
#include "externalAPI/i_pathengine.h" #include <stdio.h> #include <assert.h> #include <stdlib.h> #include <cstring> class cOperatorNewAllocator : public iAllocator { public: uint32_t _count; cOperatorNewAllocator() { _count = 0; } ~cOperatorNewAllocator() { if(_count != 0) { printf("Error, memory allocation count did not return to zero.\n"); } } void* allocate(uint32_t size) { assert(size); void* result = operator new(static_cast<size_t>(size)); ++_count; return result; } void deallocate(void* ptr) { if(ptr) { --_count; operator delete(ptr); } } void* expand(void* oldPtr, uint32_t oldSize, uint32_t oldSize_Used, uint32_t newSize) { assert(oldPtr); assert(oldSize); assert(oldSize_Used <= oldSize); assert(newSize > oldSize); void* newPtr = allocate(newSize); memcpy(newPtr, oldPtr, static_cast<size_t>(oldSize_Used)); deallocate(oldPtr); return newPtr; } }; |
Documentation for PathEngine release 6.04 - Copyright © 2002-2024 PathEngine | next: |