Newer
Older
c-interpreter / modules / libkc / include / kc_memory.h
Nomura Kei on 8 Jun 2023 3 KB UPDATE
////////////////////////////////////////////////////////////////////////////////
//
//  メモリ管理モジュール ヘッダファイル
//  @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