错误释放结构体中数组的指针导致的AddressSanitizer: attempting free on address which was not malloc()问题

前言:

这是一个初学者不经意间就会犯的错误,这也困扰了本人几天,如果这篇文章对你有帮助,希望能获得你的一颗小点赞,这便是我继续下去的最大动力。本文纯属对所经历的错误做的一个小小的记录,若有其他指导意见或自己的见解,可以评论区与我畅谈。本题是释放了不是malloc的空间导致错误。

错题目录

结构体初始化

结构体释放

呈现的错误

原因

反思回顾


结构体初始化

//结构体1
typedef struct
{
	int* arr;
	int capacity;
}ST;
   
void StackInit(ST* ps)                           //结构体初始化
{
	assert(ps);
	ps->arr = malloc(4*sizeof(int));      //malloc数组存放数据
	ps->capacity = 0;                            //记录容量
}


//结构体2
typedef struct {     
	ST push;                                     //结构体2包含两个结构体变量
	ST pop;
} MyQueue;

MyQueue* myQueueCreate() {
	MyQueue* queue = (MyQueue*)malloc(sizeof(MyQueue));   //结构体2也是malloc出来的
	StackInit(&queue->push);
	StackInit(&queue->pop);
	return queue;
}

 两个结构体的之间的关系如图:

结构体释放

//结构体1释放
void StackDestroy(ST* ps)
{
	free(ps->arr);
	ps->capacity = 0;
	ps->top = 0;
	ps->arr = NULL;
    free(ps)
}

//结构体2释放
void myQueueFree(MyQueue* obj) {
	StackDestroy(&obj->push);
	StackDestroy(&obj->pop);          //利用stack销毁,实现queue销毁
    free(obj);                        //这里在统一释放queue的内容
    obj= NULL;
}

呈现的错误

=================================================================
==42==ERROR: AddressSanitizer: attempting free on address which was not malloc()-ed: 0x603000000020 in thread T0
    #0 0x7f1bebad87cf in __interceptor_free (/lib/x86_64-linux-gnu/libasan.so.5+0x10d7cf)
    #4 0x7f1beae930b2 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x270b2)
0x603000000020 is located 16 bytes inside of 32-byte region [0x603000000010,0x603000000030)
allocated by thread T0 here:
    #0 0x7f1bebad8bc8 in malloc (/lib/x86_64-linux-gnu/libasan.so.5+0x10dbc8)
    #4 0x7f1beae930b2 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x270b2)
SUMMARY: AddressSanitizer: bad-free (/lib/x86_64-linux-gnu/libasan.so.5+0x10d7cf) in __interceptor_free
==42==ABORTING

原因

void StackDestroy(ST* ps)
{
	free(ps->arr);
	ps->capacity = 0;
	ps->top = 0;
	ps->arr = NULL;
    //free(ps)                    //这里错误!!!
}

解释:释放了不属于malloc的空间 attempting free on address which was not malloc()-ed,由于queue结构体是一次malloc创建的,怎么申请就要怎么释放,不能分多次释放,上图free(ps)是释放了push这个结构体,但是由关系图可知push和queue是指向同一个位置的,而且queue又是一次性malloc建立的,故free(ps)也就是free(&push)就连同pop所在的一整块queue一起释放了。再次访问StackDestroy(&obj->pop) 时pop已经不存在。无法再次释放。

反思回顾

注意malloc要怎么创建怎么释放,注意每个函数调用的任务,StackDestroy是释放结构体1里面的数组arr的存储空间,再由myQueueFree释放queue的空间也就是释放push和pop的空间。

StackDestroy(&obj->pop);
StackDestroy(&obj->push);          

同样的若保留free(ps),这两个函数交换释放也是不行的,释放一次malloc不能分两次释放,先释放pop,那么释放push的时候又会再次释放一次pop的空间。也是同样的错误。

所以pop和push是queue动态分配的,也要由释放queue统一释放。最重要的是怎么创建怎么释放,函数的任务要分清楚。

  • 8
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值