C语言--操作内存的工具
C语言–操作内存的工具
C语言本身作为一个操作内存的工具,在数据使用方面都需要直接申请、释放内存,在编码过程中往往不可避免出现一些内存使用的错误。下面一些常用的编码技巧,能帮组尽量减速或排查错误。
一、内存分配
static addr_record cr[256] = {0};
static addr_record fr[256] = {0};// 4 2 2 4 4
// ptr + size + free + red_zone + data + red_zone
void* app_malloc(long size)
{void *data = NULL;if (size <= 0) {APP_ERROR("size %l error", size);return data;}char *ptr = (char *)malloc(size + 4 + 2 + 2 + 4 + 4);if (NULL == ptr) {APP_ERROR("malloc size %l failed", size);return data;}data = ptr + 12;long address = (long)data;*((long *) ptr) = address;*((short*) (ptr+4)) = size;*((short*) (ptr+6)) = 0; *((long*) (ptr+8)) = 0x6e6e6e6e; *((long*) ((char*)data + size)) = 0x6e6e6e6e;memset(data, 0x0, size);if (size < 256) {cr[size].addr = address;cr[size].size = size;cr[size].num ++;}return data;
}
申请一块内存,在内存前后添加上自拟的字段(也可以理解成协议),例子中最前4个字节是申请内存的首地址,再后2个字节是申请内存大小,再后2字节填0,再后4字节填自定义数,方便查找,申请内存的最后也附上自定义数(自定义数的作用可以方便查找内存开始的地方,也方便做内存间隔断的标识)。
void app_free(void *data) {if (NULL == data) {return;}char *ptr = (char*) data - 12;if (*((long*) (ptr+8)) != 0x6e6e6e6e) {APP_ERROR("Memory out of bounds");}short size = *((short*) (ptr+4));if (size < 0) {APP_WARN("some one do not use app malloc ?");} else {if (size < 256) {fr[size].size = size;fr[size].num ++;}}free(ptr);return;
}
释放内存时也需要向前移动地址,把之前自定义部分包含进去,若报错则可能出现内存问题。
typedef struct {long addr;int size;int num;
} addr_record;
结构体主要用来计数,计算malloc和free次数,方便查内存溢出等问题;
例子
现象:Segmentation fault.
排查过程:gdb运行模式下排查:首先bt查看代码错误位置

确定代码错误发生在app_trigger函数,f 0进入栈查看frame是否正常

确认frame正常则查看entry地址(app_trigger函数参数)

发现entry是个错误地址,再看g_app_ptr缓存中的4个链表指针,发现第二、第三链表的指针地址都存在问题;打印g_app_ptr缓存的内容

根据红框中的数值发现内存并未被越界操作,所以确定是代码本身操作g_app_ptr缓存不当。其中红框中的值是分配g_app_ptr时在其周围设置的防越界标志。
再看代码逻辑,发现app_trigger 调用时可能出现g_app_ptr缓存未初始化或者entry还未注册添加到g_app_ptr缓存中,所以确认是此处可能造成调用顺序不当导致内存错误。
二、内存连续性
内存malloc次数过多会导致内存块连续性降低,内存数据查找速率下降;在结构体内部存在指针,为了避免内存不连续,在给结构体内分配内存时,同时给结构体内部的指针分配对应大小的内存。
typedef struct my_type_s {struct list_head list;int repeate;int up_period;/*更新时间*/int priority; /*优先级*/char *info; /*背景详细信息,复杂引导信息*/} my_type_t;
以上结构体包含一个char指针,一般在使用该结构体的时候先malloc(sizeof(my_type_t))内存,然后再进行my_type_t->info的内存分配并初始化;但建议在分配my_type_t结构体内存的同时分配info的内存,编码如下:
my_type_t* my_malloc(int priv_size) {my_type_t *my_type = NULL;my_type = (my_type_t *)app_malloc(sizeof (my_type_t) + priv_size);if (NULL == my_type) {ERROR("malloc event failed");return my_type;}my_type->info = (char *)my_type + sizeof (my_type_t);return event;
}
void event_free(my_type_t *my_type) {app_free(my_type);return;
}
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
