前言 - 内存越界处理
我们先看设计图. 内存越界检查原理如下
上面原理是不是很简单. 而这恰恰是最通用的做法. 美的东西不负责. 美很重要.
那我们按照上面设计思路. 首先构建 接口文件 checkmem.h
#ifndef _H_MEMCHECK_CHECKMEM
#define _H_MEMCHECK_CHECKMEM
#include <stddef.h>
/*
* 对malloc进行的封装, 添加了边界检测内存块
* (inline 原本分_DEBUG有宏处理, 后面没加等于没用)
* sz : 申请内存长度
* : 返回得到的内存首地址
*/
extern inline void* mc_malloc(size_t sz);
/*
* 对calloc进行封装, 添加边界检测内存块
* cut : 申请的个数
* sz : 每个的大小
*/
extern inline void* mc_calloc(size_t cut, size_t sz);
/*
* 对relloc进行了封装, 同样添加了边间检测内存块
*/
extern inline void* mc_realloc(void* ptr, size_t sz);
/*
* 对内存检测, 看是否出错, 出错直接打印错误信息
* 只能检测, check_* 得到的内存
*/
extern inline void mc_check(void* ptr);
#endif // !_H_MEMCHECK_CHECKMEM
主要是对 malloc, calloc, realloc 进行添加尾部和头部的内存块处理. 就这么简单一步. 假如能看懂上面设计思路图.
这些代码都可以跳过了. 思路比代码重要. 好那我们继续展现实现部分. checkmem.c
#include "checkmem.h"
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
// 控制台打印错误信息, fmt必须是双引号括起来的宏
#define CERR(fmt, ...) \
fprintf(stderr,"[%s:%s:%d][error %d:%s]" fmt "\r\n",\
__FILE__, __func__, __LINE__, errno, strerror(errno), ##__VA_ARGS__)
//控制台打印错误信息并退出, t同样fmt必须是 ""括起来的字符串常量
#define CERR_EXIT(fmt,...) \
CERR(fmt,##__VA_ARGS__),exit(EXIT_FAILURE)
// 插入字节块的个数
#define _INT_CHECK (1<<4)
/*
* 对malloc进行的封装, 添加了边界检测内存块
* sz : 申请内存长度
* : 返回得到的内存首地址
*/
inline void*
mc_malloc(size_t sz) {
// 头和尾都加内存检测块, 默认0x00
char* ptr = calloc(1, sz + 2 * _INT_CHECK);
if (NULL == ptr) {
CERR_EXIT("malloc sz + sizeof struct check is error!");
}
//前四个字节保存 最后一个内存块地址 大小