/** * @file scpp_memory.hpp * @bried メモリ管理モジュールヘッダーファイル * @author Nomura Kei * @copyright 2003 - 2022 Nomura Kei */ #ifndef SCPP_MEMORY_HPP #define SCPP_MEMORY_HPP #include <new> #include <string> #include <scpp_compiler.h> namespace scpp { /** * メモリの確保/解放/エラー発生時に呼び出されるリスナインタフェース。 * ユーザーは、本リスナを実装し、MemoryManager::setHandler メソッドにて登録することで、 * メモリの確保/解放/エラー発生時の通知を受信することが可能です。 * * 本リスナは、MemoryManager で管理しているメモリに対してのみ有効です。 * (MemoryManager::malloc, MemoryManager::calloc, MemoryManager::realloc) * * new, malloc, calloc などを対象とする場合、 * ENABLED_MEMORY_MANAGE を定義してください。 */ 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; virtual ~MemoryListener() = 0; }; /** * メモリ確保/解放/エラー発生時のデフォルト通知インタフェースです。 */ class DefaultMemoryListener : public MemoryListener { public: DefaultMemoryListener(); DefaultMemoryListener(const DefaultMemoryListener&) = delete; void operator=(const DefaultMemoryListener&) = delete; virtual ~DefaultMemoryListener(); virtual void notifyAlloc(const MemoryInfo& info); virtual void notifyFree(const MemoryInfo& info); virtual void notifyError(const MemoryInfo& info, const std::string& msg); }; /** * メモリ管理。 * メモリの確保、解放を行います。 * ハンドラを登録することで、メモリの確保/解放/エラー時の通知を受信することができます。 */ namespace MemoryManager { extern thread_local const char* fileName; extern thread_local int lineNumber; extern thread_local 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); } } #if (ENABLED_MEMORY_MANAGE) #if IS_SUPPORTED_CPP20 #define SCPP_NODISCARD [[nodiscard]] #else #define SCPP_NODISCARD #endif SCPP_NODISCARD void* operator new(std::size_t size); SCPP_NODISCARD void* operator new[](std::size_t size); SCPP_NODISCARD void* operator new(std::size_t size, const std::nothrow_t& t) noexcept; SCPP_NODISCARD void* operator new[](std::size_t size, const std::nothrow_t& t) noexcept; // void operator delete(void* ptr) noexcept; void operator delete(void* ptr, std::size_t size) noexcept; void operator delete(void* ptr, const std::nothrow_t& t) noexcept; void operator delete[](void* ptr, const std::nothrow_t& t) noexcept; // 実質メモリ管理しないので除外 // SCPP_NODISCARD void* operator new(std::size_t size, void* ptr) noexcept; // SCPP_NODISCARD void* operator new[](std::size_t size, void* ptr) noexcept; #if IS_SUPPORTED_CPP17 // 以下、未サポート // SCPP_NODISCARD void* operator new(std::size_t size, std::align_val_t alignment); // SCPP_NODISCARD void* operator new[](std::size_t size, std::align_val_t alignment); // SCPP_NODISCARD void* operator new(std::size_t size, std::align_val_t alignment, const std::nothrow_t&) noexcept; // SCPP_NODISCARD void* operator new[](std::size_t size, std::align_val_t alignment, const std::nothrow_t&) noexcept; // // void operator delete(void* ptr, std::align_val_t alignment) noexcept; // void operator delete(void* ptr, size_t size, std::align_val_t alignment) noexcept; // void operator delete(void* ptr, size_t size, std::align_val_t alignment, const std::nothrow_t& t) noexcept; // #endif #define new \ ((scpp::MemoryManager::fileName = __FILE__, \ scpp::MemoryManager::lineNumber = __LINE__, \ scpp::MemoryManager::functionName = __func__, \ 0) && 0) ? 0 : new #define malloc(size) scpp::MemoryManager::malloc( size, __FILE__, __LINE__, __func__) #define calloc(nmemb, size) scpp::MemoryManager::calloc(nmemb, size, __FILE__, __LINE__, __func__) #define realloc(ptr, size) scpp::MemoryManager::realloc(ptr , size, __FILE__, __LINE__, __func__) #define free(ptr) scpp::MemoryManager::free(ptr) #endif // (ENABLED_MEMORY_MANAGE) #endif // SCPP_MEMORY_HPP