设为首页 加入收藏

TOP

C基础 内存越界和内存监测的简单处理(二)
2017-10-12 17:41:11 】 浏览:1802
Tags:基础 内存 越界 监测 简单 处理

注释等价无, 你是什么感受. 为我们多留条后路, 多写注释.

好 看测试代码 main.c

#include <stdio.h>
#include <stdlib.h>
#include "checkmem.h"

/*
 * 演示一种检测内存越界的办法
 * 添加上下限方式
 */
int main(int argc, char* argv[]) {

    // 实验步骤是, 是申请内存, 在操作内存
    char* as = mc_malloc(16);

    mc_check(as);

    // 内存越界了
    //as[16] = 18;
    //mc_check(as);

    // 重新分配内存, 再次越界
    as = mc_realloc(as, 15);
    as[15] = 44;
    mc_check(as);

    free(as);
    return 0;
}

 测试结果

到这里内存越界的思路和实现都已经完毕了.欢迎思考尝试.

 

正文 - 内存全局监测

  内存全局检测思路更简单. 采用引用'计数方式'处理. 扯一点很多自动垃圾回收机制都采用了引用计数方式.

包括内核层例如 文件描述符, IPC 共享内存, 消息机制等.  先看接口 memglobal.h

#ifndef _H_MEMGLOBAL_MEMGLOBAL
#define _H_MEMGLOBAL_MEMGLOBAL

#include <stddef.h>
#include <stdlib.h>

/*
 * 全局启动内存简单监测
 */
extern inline void mg_start(void);

/*
 * 增加的全局计数的 malloc
 * sz        : 待分配内存大小
 *            : 返回分配的内存首地址
 */
extern void* mg_malloc(size_t sz);

/*
 * 增加了全局计数的 calloc
 * sc        : 分配的个数
 * sz        : 每个分配大小
 *            : 返回分配内存的首地址
 */
extern inline void* mg_calloc(size_t sc, size_t sz);

/*
 * 增加了计数的 realloc
 * ptr        : 上一次分配的内存地址
 * sz        : 待重新分配的内存大小
 *            : 返回重新分配好的内存地址
 */
extern void* mg_realloc(void* ptr, size_t sz);

/*
 * 增加了计数处理的内存 free
 * ptr        : 上面函数返回地址的指针
 */
extern inline void mg_free(void* ptr);

// 在测试模式下开启 全局内存使用计数
#if defined(_DEBUG)
#    define malloc        mg_malloc
#    define calloc        mg_calloc
#    define realloc        mg_realloc
#    define free            mg_free
#else
#    define malloc        malloc
#    define calloc        calloc
#    define realloc        realloc
#    define free            free
#endif

#endif // !_H_MEMGLOBAL_MEMGLOBAL

 还是比较优美的. 再看 memglobal.c

#include "memglobal.h"
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>

// 取消内置宏, 防止递归
#undef malloc
#undef calloc
#undef realloc
#undef free

// 控制台打印错误信息, fmt必须是双引号括起来的宏
#define IOERR(io, fmt, ...) \
    fprintf(io,"[%s:%s:%d][error %d:%s]" fmt "\r\n",\
         __FILE__, __func__, __LINE__, errno, strerror(errno), ##__VA_ARGS__)

// 全局内存计数, 系统第一次构造的时候为0
static int _mct;

#define _STR_MGTXT    "checkmem.log"

// mg内存监测退出时候, 记录一些信息
static void _mg_exit(void) {
    if (_mct == 0) return;

    // 先打印信息到控制台
    IOERR(stderr, "Detect memory leaks _mct = %d!!", _mct);

    //输出到文件
    FILE* txt = fopen(_STR_MGTXT, "a");
    if (txt == NULL) {
        IOERR(stderr, "fopen " _STR_MGTXT " a is error!");
        return;
    }
    IOERR(txt, "Detect memory leaks _mct = %d!!", _mct);
    fclose(txt);
}

/*
* 全局启动内存简单监测
*/
inline void 
mg_start(void) {
    // 注册退出监测事件
    atexit(_mg_exit);
}

/*
* 增加的全局计数的 malloc
* sz        : 待分配内存大小
*            : 返回分配的内存首地址
*/
void* 
mg_malloc(size_t sz) {
    void* ptr = malloc(sz);
    if (!ptr) return NULL;
    ++_mct;
    memset(ptr, 0x00, sz);
    return ptr;
}

/*
* 增加了全局计数的 calloc
* sc        : 分配的个数
* sz        : 每个分配大小
*            : 返回分配内存的首地址
*/
inline void* 
mg_calloc(size_t sc, size_t sz) {
    return mg_malloc(sc*sz);
}

/*
* 增加了计数的 realloc
* ptr        : 上一次分配的内存地址
* sz        : 待重新分配的内存大小
*            : 返回重新分配好的内存地址
*/
void* 
mg_realloc(void* ptr, size_t sz) {
    if (!ptr) return mg_malloc(sz);
    return realloc(ptr, sz);
}

/*
* 增加了计数处理的内存 free
* ptr        : 上面函数返回地址的指针
*/
inline void
mg_free(void* ptr) {
    if (!ptr) return;
    --_mct;
    free(ptr);
}

 中间用了

// 取消内置宏, 防止递归
#undef malloc
#undef calloc
首页 上一页 1 2 3 下一页 尾页 2/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇使用C语言将pcm数据封装成wav文件.. 下一篇338. Counting Bits

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目