/** \file memoryallocator.hpp * * This file provides wrappers for C++'s memory allocation functions. */ #ifndef MEMORYALLOCATOR_HPP_ #define MEMORYALLOCATOR_HPP_ using namespace std; /*********************************************** includes ***********************************/ // include config.h #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #include #include #include #include "defs.hpp" #include "verbose.hpp" #include "memoryusageobserver.hpp" /********************************************** declarations *******************************/ /** Allocates a memory range using malloc(). * Prints the provided error message in case of a failure. * * \param number of memory slices of type X to allocate * \param failure message which is printed if the allocation fails * \return pointer to the allocated memory range, will be NULL if a failure occurred */ template X* Malloc(size_t size, const char* output) { X* buffer = NULL; buffer = (X*) malloc(sizeof(X) * size); if (buffer != NULL) { MemoryUsageObserver::getInstance()->addMemory(buffer, size); } else { cout << Verbose(0) << "Malloc for datatype " << typeid(X).name() << " failed - pointer is NULL: " << output << endl; } return buffer; }; /** \see helpers.cpp for Malloc */ template <> char* Malloc(size_t size, const char* output); /** Allocates a memory range using calloc(). * Prints the provided error message in case of a failure. * * \param number of memory slices of type X to allocate * \param failure message which is printed if the allocation fails * \return pointer to the allocated memory range, will be NULL if a failure occurred */ template X* Calloc(size_t size, const char* output) { X* buffer = NULL; buffer = (X*) calloc(sizeof(X) * size, (size_t) 0); if (buffer != NULL) { MemoryUsageObserver::getInstance()->addMemory(buffer, size); } else { cout << Verbose(0) << "Calloc for datatype " << typeid(X).name() << " failed - pointer is NULL: " << output << endl; } return buffer; }; /** Reallocates a memory range using realloc(). If the provided pointer to the old * memory range is NULL, malloc() is called instead. * Prints the provided error message in case of a failure (of either malloc() or realloc()). * * \param pointer to the old memory range * \param number of memory slices of type X to allocate * \param failure message which is printed if the allocation fails * \return pointer to the reallocated memory range, will be NULL if a failure occurred */ template X* ReAlloc(X* OldPointer, size_t size, const char* output) { X* buffer = NULL; if (OldPointer == NULL) { buffer = (X*) malloc(sizeof(X) * size); } else { buffer = (X*) realloc(OldPointer, sizeof(X) * size); MemoryUsageObserver::getInstance()->removeMemory(OldPointer); } if (buffer != NULL) { MemoryUsageObserver::getInstance()->addMemory(buffer, size); } else { cout << Verbose(0) << "ReAlloc for datatype " << typeid(X).name() << " failed - new is NULL: " << output << endl; } return buffer; }; /** Frees allocated memory range using free(). * * \param pointer to the allocated memory range to free; may be NULL, this function is a no-op then * \param *msg optional error message */ template void Free(X** buffer, const char *msg = NULL) { if ((buffer == NULL) || (*buffer == NULL)) return; MemoryUsageObserver::getInstance()->removeMemory(*buffer, msg); free(*buffer); *buffer = NULL; }; #endif /*MEMORYALLOCATOR_HPP_*/