写过 C/C++ 的都知道,内存允许程序员自主分配,用完了这些资源也得释放出来,这种在系统运行过程中动态申请的内存,称为动态内存。
(相关资料图)
常言道,借东西好借好还,下次再借也不难,但是有的人有时候还真的忘了还回去。这要是发生在程序运行时,申请的内存没正常释放,没管理好,就避免不了会面对内存报错的问题。
内存都允许你自由操纵了,灵活性是真的大,恰恰这也是它的弊端。
今天就来聊聊 C/C++ 的报错double free or corruption
C 语言提供了两个函数用于分配和释放内存 malloc 和 free,需要引用头文件
#include#include int main() { int *ptr = malloc(sizeof(int)); *ptr = 100; printf("%d", *ptr); free(ptr); return 0; }
输出:
100
调用 malloc 会分配一块内存空间,并将这块内存空间的首地址返回。调用时,需要传入目标内存空间的大小,单位按照字节(Byte)算,而返回的地址数据类型是 void*,所以,根据目标空间的具体用途转换即可。
这块内存空间在分配之后还属于未初始化的状态,如果对内存空间的使用比较复杂,建议先用 memset 初始化一下。
内存空间使用完,需要使用 free 释放掉,避免闲置浪费,否则就算是内存泄漏了。内存泄露会直到程序进程结束为止。
在其它的高级语言里,比如 Java、Python 等,出于内存安全的考虑,都不会允许用户自己管理内存,而 C++ 是个例外,这可能来自于 C 语言的传承。
C++ 里同样提供了 malloc 和 free,但是引用的头文件变成了
另外 C++ 还提供了两个额外的操作符用于分配和释放内存,分别是 new 和 delete。
#includeusing namespace std; int main() { int *ptr = new int; *ptr = 100; cout << *ptr << endl; delete ptr; return 0; }
输出:
100
关键词 new 后接上一个数据类型,然后分配和数据类型 int 对应大小的内存空间,并返回首地址。对应地,new 申请的内存空间被使用完不再需要时,应该使用关键词 delete 释放,delete 直接操作内存空间首地址。
借来的钱用得可以很爽,是的,常人都这样。不过,每到要还钱的时候就特别不情愿,要么推三推四,要么直接抵赖,一不留神就忘了是否有还过这事。
比如,张三本来一直在外租房将就着过日子,随着家里人口逐渐增多,就和老婆合计着从银行贷了一笔资金准备买房嘛,贷了款之后,银行贷款经理就告诉他,“张先生,你们家以后每月就得由一名代表人来还贷款,不需要几个人同时还的,记住了哈!”
好了,这个故事给了我们什么启发呢?就是资金或者资源的借入借出需要有一个管理人,这样可以避免混乱进而出错。
同样的,在 C/C++ 的编程里边,经常会出现一些内存资源管理混乱而出现的报错甚至运行时崩溃的问题,比如 double free or corruption。
#includeusing namespace std; int main() { int *ptr = new int; *ptr = 100; cout << *ptr << endl; delete ptr; delete ptr; return 0; }
执行
100 free(): double free detected in tcache 2 Aborted (core dumped)
程序执行崩溃并报错 double free,根本原因是对同一内存地址调用了多次的 free 或 delete 执行释放,这会导致应用的内存管理数据结构被损坏,甚至会允许恶意用户在内存任意区域写入数据。这类损坏会导致程序崩溃或者程序的部分执行流程被改变。如果攻击者这个时候特意覆盖特定的寄存器或者内存区域来引导执行他们的代码,进而可以产生提升权限的交互式 shell,这样就完全被破防了。
这也算是内存泄漏的一种,系统一旦检测到 double free 也会终止进程继续执行(Aborted)。
一块内存被释放之后,空闲的内存会被放入链表中,用于重新管理和组合不同的空闲内存碎片,便于将来用于分配更大的内存空间。这个链表属于双向链表,每个空闲的内存空间都可以往前和往后查找其它内存空间。
那么攻击者可以利用这个过程吗?
答案是肯定的。当 free 被调用时,攻击者可以让原本需要被链表管理的空闲内存取消链接,覆盖寄存器值并从缓冲区载入shell代码,最终往内存写入任意值。
上面的示例代码简单演示了 double free 的触发,平常出现这种报错的条件并不比上面的情形要复杂多少。比如,释放同一块内存的动作在相隔了几百甚至更多行的位置执行,有的还发生在不同源码文件,这就会让程序员容易多次释放。下面尝试总结一下,来看一下常见的犯错情形:
释放前判断的条件错误或者其它不常见的情况内存被释放后还在使用内存释放的管理责任方混乱其实,细看一下上面总结的几种常见犯错情形,我们也可以很好地避免低级错误。
有个最佳实践是,分配的内存地址存储变量 ptr 在定义声明时就应该初始化为 NULL,内存被释放后应立刻将 ptr 置为 NULL,使用这块内存或者释放前应该遵循先判断内存空间是否有效的原则,简单点可以用 (ptr != NULL)。
另外,负责释放的管理责任方应该尽量单一,即使横跨多个源文件或模块。这里有个道理就是避免”多龙治水“。
中国在过去一直是个农业大国,有着重农轻商的历史,各种典故都有着农业的影子。
相传,几龙治水、几牛耕地那是对当年农业收成的预示,不妨翻一下老黄历看看?“龙”是管雨的神,以五龙治水可获风调雨顺,因东南西北中都有神龙,各施其职。龙少了当年就要发大水;龙多了当年将要天大旱。原因是管雨的龙神少了怕管不过来,就忙忙碌碌四处播雨以至大涝;管雨的龙神多了呢,就像“三个和尚无水吃”一样以至大旱。至于涝到什么程度还看治水的龙少到什么程度,龙越少涝得越严重。旱的程度亦一样。
因此就有了“龙多不下雨”的谚语。
计算机编程说到底还是程序员的思维体现,人情世故也会反映在代码的逻辑上。
以上就是C/C++出现double free or corruption问题解决的详细内容,更多关于C/C++ double free or corruption的资料请关注脚本之家其它相关文章!
这篇文章主要为大家介绍了C C++出现doublefreeorcorruption问题解...
1、《英诗华章:汉泽注释评析》是2015年中央编译出版社出版的图书。...
中新社重庆4月3日电题:随马英九访大陆台湾学子:两岸最重要的是多...
新年礼物送这些给员工,新年就要到了,公司准备给员工送去一个新年...
早春3月的帕米尔高原,有皑皑雪山、万年冰川,也有奔腾的河水、遍地...
爱浪音响怎么接,爱浪音响怎么样很多人还不知道,小城来为大家解答...
00:32家住上海市普陀区祁安路368弄2号楼的居民潘女士反映,自己已经...
我们理解扁平疣的危害有很大,如果不根据本身的情况选取适宜自...
香港特区政府统计处31日发表最新零售业销货额数字显示,2023年2月香...
产品3月31日4月3日涨跌幅单位:元 吨萤石3037 53043 750 21%元...
项目名称:俄歇电子显微镜项目编号:0811-234DSITC0216招标范围:俄...
新京报贝壳财经讯易居(中国)企业控股有限公司4月3日公布境外债重组...
前言祝贺男篮新增5大巨星,巩晓彬儿子跟新版本的郭艾伦重磅崛起,外...
“春季攻势”暨“春季守护行动”开展以来,株洲公安交警持续发力,...
森林狼爆冷输开拓者引湖人队记热议!若湖人赢火箭将领先2胜场,火箭,...
香椿炒鸡蛋是一道常见的家常菜,由于香椿具有清香味道,而鸡蛋则富...
中端机市场竞争已日趋白热化。据小米官方信息显示,凭借出色全能体...
天津北方网讯:3月31日,一场春回鸟归千里护行国际爱鸟日共建活动在...
头部效应愈演愈烈。截至4月1日,已有23家上市券商披露年报。其中,...
前不久,临夏回族自治州一位车主的纸条留言和交警开出的“温馨提示...
长安深蓝已提车用户享终身整车质保!但有些条件
华大基因公布财报,2022年营收增长4 14%至70 46亿元,研发投入同...
海关总署关于废止部分规章的决定海关总署第261号令(2023年3月7日海...
身材高大的天才中卫目前已经是本菲卡在后防线上的绝对核心,在联赛...
阿里巴巴(中国)有限公司近日公开一项“高分辨率虚拟换装方法、系...
1、展开3全部张无忌他妈临死前说的话是:越是好看的女人越会骗人。2...
1、春雨惊春清谷天,夏满芒夏暑相连,秋处露秋寒霜降,冬雪雪冬小大...
小学生《人与自然和谐共生》主题绘画获奖作品6月1日缅甸馆日展示当...
30MW智慧能源项目落地海南琼海
送她一些比较实用的礼物就好了,比如说智能手表,发夹,发夹、发...