////////////////////////////////////////////////////////////////////////////////
//
// メモリ管理モジュール ヘッダファイル
// @copyright 2003 - 2023 Nomura Kei
//
#ifndef KC_MEMORY_H
#define KC_MEMORY_H
#include <kc.h>
#ifdef __cplusplus
extern "C" {
namespace kc {
using namespace std;
#endif
#ifdef KC_MEMORY_ENABLED
// メモリ管理有効
#define malloc(size) kc_memory_malloc ( size, __FILE__, __func__, __LINE__)
#define calloc(nmemb, size) kc_memory_calloc (nmemb, size, __FILE__, __func__, __LINE__)
#define realloc(ptr, size) kc_memory_realloc(ptr , size, __FILE__, __func__, __LINE__)
#define free(ptr) kc_memory_free (ptr)
#else
#include <stdlib.h>
#endif // !KC_MEMORY_ENABLED
// 管理メモリ種別を表すための識別マーク
#define KC_MEMORY_MARK_HEAD (0x55AA5A00)
#define KC_MEMORY_MARK_MASK (0xFFFFFF00)
typedef enum
{
KC_MEMORY_DELETED = KC_MEMORY_MARK_HEAD | 0x00, //!< メモリが解放されている
KC_MEMORY_ALLOCATED = KC_MEMORY_MARK_HEAD | 0x01, //!< メモリが確保されている
KC_MEMORY_ALLOCATED_NEW = KC_MEMORY_MARK_HEAD | 0x02, //!< new により確保されたメモリ
KC_MEMORY_ALLOCATED_NEW_ARRAY = KC_MEMORY_MARK_HEAD | 0x03 //!< new[] により確保されたメモリ
} KcMemoryMark;
/**
* ダンプサイズ
*/
#define KC_MEMORY_DUMP_SIZE (16)
/**
* 指定されたメモリ管理用種別マークが正しいか判定します。
*
* @param mark 種別マーク
* @return true/false (管理されているメモリ/管理されていないメモリ)
*/
#define kc_memory_is_valid_mark(mark) ((mark & KC_MEMORY_MARK_MASK) == SC_MEMORY_MARK_HEAD)
/**
* メモリエントリ。
*/
typedef struct KcMemoryEntry_
{
const char* file; /*!< メモリ確保ファイル名 */
const char* func; /*!< メモリ確保関数名 */
int line; /*!< メモリ確保行番号 */
int size; /*!< 確保サイズ */
int _mark; /*!< 確保メモリ状態 */
struct KcMemoryEntry_* _prev; /*!< 前の管理メモリポインタ */
struct KcMemoryEntry_* _next; /*!< 次の管理メモリポインタ */
void* data; /*!< データ */
// 構造体末尾の配列に限りサイズ省略可能 (C99 : incomplete array)
} KcMemoryEntry;
// ハンドラ関数ポインタ
typedef bool (*KcMemoryHandler)(KcMemoryEntry* entry, const char* msg);
// プロトタイプ宣言
void kc_memory_set_handlers(KcMemoryHandler allocate, KcMemoryHandler free, KcMemoryHandler error);
bool kc_memory_entries(KcMemoryHandler handler);
bool kc_memory_freeif(KcMemoryHandler handler);
void kc_memory_dump(void);
// 以下は、通常直接使用しません。
void* kc_memory_malloc ( size_t size, const char* file, const char* func, int line);
void* kc_memory_calloc (size_t nmemb, size_t size, const char* file, const char* func, int line);
void* kc_memory_realloc(void* ptr , size_t size, const char* file, const char* func, int line);
void kc_memory_free (void* ptr);
#ifdef __cplusplus
} // namespace kc
} // extern "C"
#endif
#endif // KC_MEMORY_H