/* ============================================================================= * scpp_memory.hpp * Copyright (c) 2003 - 2011 Nomura Kei * LICENSE : * LGPL (GNU Lesser General General Public License - Version 3,29 June 2007) * http://www.gnu.org/copyleft/lesser.html * ============================================================================= * * メモリ管理モジュール. */ #ifndef SCPP_MEMORY_HPP #define SCPP_MEMORY_HPP #include <new> #include <string> #include <scpp_compiler.hpp> namespace scpp { /** * メモリ管理情報. * メモリを確保したソースファイル名, 行番号, 関数名, * 確保したメモリサイズを表します. */ struct MemoryInfo { const char* fileName; int lineNumber; const char* functionName; int size; int _mark; MemoryInfo* _prev; MemoryInfo* _next; void* _data; }; /** * メモリが確保, 開放, あるいはメモリ確保/開放時にエラーが発生した際のリスナインタフェース. * ユーザは, 本リスナを実装し, MemoryManager::setHandler メソッドにて登録することで, * メモリの確保, 開放, エラー発生時の通知を受信することが可能です. * * 本リスナは MemoryManager にて管理しているメモリ * (MemoryManager::malloc, MemoryManager::calloc, MemoryManager::realloc) * に対してのみ有効です. * * new や, malloc, calloc 等を対象としたい場合, SCPP_DEBUG を有効にしてください. */ class MemoryListener { public: virtual void notifyAlloc(const MemoryInfo& info) = 0; virtual void notifyFree(const MemoryInfo& info) = 0; virtual void notifyError(const MemoryInfo& info, const std::string& msg) = 0; }; /** * メモリ確保, 開放, メモリ確保/開放時にエラー発生した際のデフォルトのインタフェースです. */ class DefaultMemoryListener : public MemoryListener { public: DefaultMemoryListener(); virtual ~DefaultMemoryListener(); virtual void notifyAlloc(const MemoryInfo& info); virtual void notifyFree(const MemoryInfo& info); virtual void notifyError(const MemoryInfo& info, const std::string& msg); }; /** * メモリ管理. * メモリの確保, 開放を行います. * ハンドラを登録することで, メモリ確保, 開放, エラー発生時の通知を受信することができます. * new 演算子呼び出し自の ファイル名, 行番号, 関数名はスレッドセーフではありません. * C++11 */ namespace MemoryManager { extern const char* fileName; extern int lineNumber; extern const char* functionName; void setListener(MemoryListener* handler); void entries (void (*handler)(const MemoryInfo& info)); void cleanup (bool (*isCleanup)(const MemoryInfo& info)); void printMemoryInfo(const MemoryInfo& info); void* malloc ( std::size_t size, const char* file, int line, const char* func); void* calloc (std::size_t nmemb, std::size_t size, const char* file, int line, const char* func); void* realloc (void* ptr , std::size_t size, const char* file, int line, const char* func); void free (void* ptr); } } // 以下, メモリ管理が有効な場合のみ #ifdef SCPP_DEBUG void* operator new(std::size_t size) throw(std::bad_alloc); void* operator new(std::size_t size, const std::nothrow_t& t) throw(); void* operator new[](std::size_t size) throw(std::bad_alloc); void* operator new[](std::size_t size, const std::nothrow_t& t) throw(); void operator delete(void* p) throw(); void operator delete(void* p, const std::nothrow_t& t) throw(); void operator delete[](void* p) throw(); void operator delete[](void* p, const std::nothrow_t& t) throw(); #define new \ ((scpp::MemoryManager::fileName = __FILE__, \ scpp::MemoryManager::lineNumber = __LINE__, \ scpp::MemoryManager::functionName = __FUNCTION__, \ 0) && 0) ? 0 : new #define malloc(size) scpp::MemoryManager::malloc ( size, __FILE__, __LINE__, __FUNCTION__) #define calloc(nmemb, size) scpp::MemoryManager::calloc (nmemb, size, __FILE__, __LINE__, __FUNCTION__) #define realloc(ptr, size) scpp::MemoryManager::realloc(ptr , size, __FILE__, __LINE__, __FUNCTION__) #define free(ptr) scpp::MemoryManager::free (ptr) #endif // SCPP_DEBUG #endif // SCPP_MEMORY_HPP