leetcode报错之 ERROR: AddressSanitizer: attempting double-free on 0x7fa0cd690800 in thread T0: ...

背景

在写 #173二叉搜索树迭代器 的时候,遇到了如下报错:

报错内容

=================================================================
==45==ERROR: AddressSanitizer: attempting double-free on 0x7fa0cd690800 in thread T0:
    #0 0x7fa0cca11b8f in __interceptor_free (/usr/lib/x86_64-linux-gnu/libasan.so.5+0x10bb8f)
    #4 0x7fa0cb9f682f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
0x7fa0cd690800 is located 0 bytes inside of 400008-byte region [0x7fa0cd690800,0x7fa0cd6f2288)
freed by thread T0 here:
    #0 0x7fa0cca11b8f in __interceptor_free (/usr/lib/x86_64-linux-gnu/libasan.so.5+0x10bb8f)
    #4 0x7fa0cb9f682f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
previously allocated by thread T0 here:
    #0 0x7fa0cca11f88 in malloc (/usr/lib/x86_64-linux-gnu/libasan.so.5+0x10bf88)
    #5 0x7fa0cb9f682f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
SUMMARY: AddressSanitizer: double-free (/usr/lib/x86_64-linux-gnu/libasan.so.5+0x10bb8f) in __interceptor_free
==45==ABORTING

翻译

管他三七二十一,先翻译一下报错信息:

ERROR: AddressSanitizer: attempting double-free

错误:尝试双重释放

实际操作

释放,free。这个关键词说明了我们的代码是在释放的时候出了问题。

于是我们去寻找有free()函数的地方:

void bSTIteratorFree(BSTIterator* obj) {
    free(obj->val);
    free(obj);
}

乍一看也没啥问题啊,先释放里面的数据结果(此处为一维数组val),然后再释放整个结构体变量。

但是转念一想,问题来了。如果obj->val本身就为空呢?这时候哪来的obj->val?释放个锤子?

解释一下,BSTIterator 是一个栈,obj->top为栈顶指针

于是在释放obj->val之前加上了判断,如下

void bSTIteratorFree(BSTIterator* obj) {
    if(obj->val) free(obj->val);
    free(obj);
}

然而这时候可以发现,也没法全A.

再仔细一想,如果结构体变量obj如果本身不存在,又何来的obj->val?

于是如下修改:

void bSTIteratorFree(BSTIterator* obj) {
    if(obj && obj->val) free(obj->val);
    free(obj);
}

这样子就解决了上面的报错问题,并完成了题目。想看看题目是啥?请点传送门

后记

诸如此类语句:

BSTIterator* obj = (BSTIterator *)malloc(sizeof(BSTIterator));
if(!obj) return NULL;
obj->top = 0;

第二行的判断语句看似可有可无,但是,如果内存空间分配失败了呢?

这样一来obj就还只是一个空指针,又何来的obj->top

异常判断,养成习惯

如果我们养成了好习惯,出现报错的概率岂不会下降很多?

自省,自省!

如果对你有帮助,请。(这是一波强烈的暗示)

你可能感兴趣的:(关于报错)