C语言中,通过malloc()函数申请的内存,free()函数释放内存,只传入一个地址,为什么能知道释放多大的内存? 在编写C/C++程序时,我们会经常和内存打交道,手动申请内存、释放内存,不知道大家有没有想过,malloc()函数申请的一块内存,用完后我们会调用free()函数释放内存,而free()函数只传入了一个地址,怎么能知道要释放多大的内存呢?接下来,我们带着这个疑问阅读下面的内容,看完就明白了。 在开始正式内容前,大家先看一下这个图,相信经常写C/C++程序的小伙伴都陌生。
图1 一般出现这个问题,都是我们操作了非法的内存地址,导致释放内存时候地址值不对,发生错误。 我们申请的内存假如是128字节,实际上系统给我们分配的内存大小是:128+16 = 144字节。前面有16字节是存储这块内存的信息,我们可用的内存是下图绿色区域,即我们申请的大小。 free()函数拿到图2箭头所指位置,然后先左偏移16个字节,便到该内存块信息,便可以释放内存。 图1所示的错误,是因为我们修改了内存块信息,即图2中灰色区域导致的。
图2 查看内存块头部信息: 写一个简单的申请内存程序 使用Linux 下的GDB对程序进行调试,查看内存值。 在getchar(); 这个位置打一个断点,查看此时内存信息。图3中绿色方框中是内存块头部信息,红色方框是用户所使用的内存。buffer1已经被我们使用0x55填充了,buffer2被我们使用0xaa填充了。注:图3中是以十六进制显示的。
图3 绿色方框中的buffer1头部信息如图4所示,只有一个0x31的值,其他都是0,0x31(十进制: 49), 49 = 32 + 16 +1,32字节是我们malloc()函数申请的大小,16字节是头部信息大小,还有1字节的偏移,所以free()函数拿到这块地址,根据头部信息才能正确的释放内存。若修改了0x31及其右边区域的值,释放内存时候将发生图1所示错误。
图4 图5绿色方框是buffer2的内存块头部信息,有一个值0x51(十进制:81),81=64 + 16 + 1,64字节是我们使用malloc()函数申请的大小,16字节是内存块头部信息,1字节的偏移。
图5 释放内存后,内存中的值:(注:在64位系统中,一个指针的大小占8个字节,在32位系统中,一个指针大小占4个字节。,小C使用的是64位系统,即一个指针占8个字节)。释放内存后,buffer1、buffer2起始位置向后8个字节被置0了,图5红色线标志所示。
图6 我是小C,欢迎大家、点赞支持,我们一起交流讨论学习!
2024最新激活全家桶教程,稳定运行到2099年,请移步至置顶文章:https://sigusoft.com/99576.html
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。 文章由激活谷谷主-小谷整理,转载请注明出处:https://sigusoft.com/47151.html