free到底做了什么?

flying_music 2020-12-16 10:28:27
经常遇到free崩溃的问题,最常见的就是内存写越界了,但只越界一点儿一般是不会崩溃的,越界多了就会崩溃。。。。
操作系统在执行free的时候,是通过什么判断该不该让程序崩溃的呢?为啥写越界的时候不去做这种检查,要到free的时候做检查呢?关键是如何检查的呢?
...全文
942 12 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
ahui5252 2020-12-19
  • 打赏
  • 举报
回复
引用 9 楼 flying_music 的回复:
[quote=引用 6 楼 ahui5252 的回复:]头部信息是必要的,涉及到内存管理,当free回收时,内存管理模块可以通过头部信息进行处理,包括碎小内存合并啊,以备再次分配使用

头部是必要的,如果要检测写越界,尾部应该也是必要的,要不free的时候就不能检测写越界了[/quote]release版本是不会检测越界的,所以尾部仅对于debug版
flying_music 2020-12-19
  • 打赏
  • 举报
回复
嗯嗯 是的 尾部作用比较单一 就是检测越界用,可以优化掉的 头部有长度信息,不能优化的
赵4老师 2020-12-18
  • 打赏
  • 举报
回复
引用 10 楼 flying_music 的回复:
[quote=引用 2 楼 赵4老师 的回复:]为什么不去研读linux源代码中malloc和free函数的实现部分呢?
还没达到赵老师的高度。。。[/quote] 源码,也只有源码面前,了无秘密。
flying_music 2020-12-17
  • 打赏
  • 举报
回复
自己写了个例子看了一下,malloc之后的内存,在返回的地址前面有一段,记录着一些数据,但具体数据结构不知道,应该是分配的长度相关的,在分配内存区域后面的几个字节,也记录着一些数据,猜测这些数据应该是内核标记的界限,free的时候会查看这些界限值是否被改写了,如果被改写了,则说明用户写越界了,还有一个实验可以证明这个猜测就是如果你不改这些区域,而是改写更后面的区域(比如分配100字节,往第150字节写东西),程序是不会崩溃的
  • 打赏
  • 举报
回复
引用 1 楼 flying_music 的回复:
自己写了个例子看了一下,malloc之后的内存,在返回的地址前面有一段,记录着一些数据,但具体数据结构不知道,应该是分配的长度相关的,在分配内存区域后面的几个字节,也记录着一些数据,猜测这些数据应该是内核标记的界限,free的时候会查看这些界限值是否被改写了,如果被改写了,则说明用户写越界了,还有一个实验可以证明这个猜测就是如果你不改这些区域,而是改写更后面的区域(比如分配100字节,往第150字节写东西),程序是不会崩溃的
分析了一下malloc的汇编代码,动态分配的大小(只是大小),存放在栈里面,而堆内存空间里面没有存放分配的大小。
赵4老师 2020-12-17
  • 打赏
  • 举报
回复
free Deallocates or frees a memory block. void free( void *memblock ); Function Required Header Compatibility free <stdlib.h> and <malloc.h> ANSI, Win 95, Win NT For additional compatibility information, see Compatibility in the Introduction. Libraries LIBC.LIB Single thread static library, retail version LIBCMT.LIB Multithread static library, retail version MSVCRT.LIB Import library for MSVCRT.DLL, retail version Return Value None Parameter memblock Previously allocated memory block to be freed Remarks The free function deallocates a memory block (memblock) that was previously allocated by a call to calloc, malloc, or realloc. The number of freed bytes is equivalent to the number of bytes requested when the block was allocated (or reallocated, in the case of realloc). If memblock is NULL, the pointer is ignored and free immediately returns. Attempting to free an invalid pointer (a pointer to a memory block that was not allocated by calloc, malloc, or realloc) may affect subsequent allocation requests and cause errors. After a memory block has been freed, _heapmin minimizes the amount of free memory on the heap by coalescing the unused regions and releasing them back to the operating system. Freed memory that is not released to the operating system is restored to the free pool and is available for allocation again. When the application is linked with a debug version of the C run-time libraries, free resolves to _free_dbg. For more information about how the heap is managed during the debugging process, see Using C Run-Time Library Debugging Support. Example /* MALLOC.C: This program allocates memory with * malloc, then frees the memory with free. */ #include <stdlib.h> /* For _MAX_PATH definition */ #include <stdio.h> #include <malloc.h> void main( void ) { char *string; /* Allocate space for a path name */ string = malloc( _MAX_PATH ); if( string == NULL ) printf( "Insufficient memory available\n" ); else { printf( "Memory space allocated for path name\n" ); free( string ); printf( "Memory freed\n" ); } } Output Memory space allocated for path name Memory freed Memory Allocation Routines See Also _alloca, calloc, malloc, realloc, _free_dbg, _heapmin
赵4老师 2020-12-17
  • 打赏
  • 举报
回复
为什么不去研读linux源代码中malloc和free函数的实现部分呢?
真相重于对错 2020-12-17
  • 打赏
  • 举报
回复
程序启动时,会形成一个或两个链表,表示未分配的内存和已分配的内存。分配内存是从未分配链表里面找到一个适合大小的内存块,并把它标记在已分配的链表下。释放则反之。不仅仅依靠已分配内存头部记录的那些信息。
flying_music 2020-12-17
  • 打赏
  • 举报
回复
引用 2 楼 赵4老师 的回复:
为什么不去研读linux源代码中malloc和free函数的实现部分呢?
还没达到赵老师的高度。。。
flying_music 2020-12-17
  • 打赏
  • 举报
回复
引用 6 楼 ahui5252 的回复:
头部信息是必要的,涉及到内存管理,当free回收时,内存管理模块可以通过头部信息进行处理,包括碎小内存合并啊,以备再次分配使用
头部是必要的,如果要检测写越界,尾部应该也是必要的,要不free的时候就不能检测写越界了
flying_music 2020-12-17
  • 打赏
  • 举报
回复
引用 4 楼 zjq9931 的回复:
[quote=引用 1 楼 flying_music 的回复:]自己写了个例子看了一下,malloc之后的内存,在返回的地址前面有一段,记录着一些数据,但具体数据结构不知道,应该是分配的长度相关的,在分配内存区域后面的几个字节,也记录着一些数据,猜测这些数据应该是内核标记的界限,free的时候会查看这些界限值是否被改写了,如果被改写了,则说明用户写越界了,还有一个实验可以证明这个猜测就是如果你不改这些区域,而是改写更后面的区域(比如分配100字节,往第150字节写东西),程序是不会崩溃的
分析了一下malloc的汇编代码,动态分配的大小(只是大小),存放在栈里面,而堆内存空间里面没有存放分配的大小。[/quote] 应该是放到堆上吧,放到栈上函数退栈后不就丢了吗?
  • 打赏
  • 举报
回复
如果“堆内存空间里面没有存放分配的大小”那free凭一个指针就能释放分配快?
ahui5252 2020-12-17
  • 打赏
  • 举报
回复
头部信息是必要的,涉及到内存管理,当free回收时,内存管理模块可以通过头部信息进行处理,包括碎小内存合并啊,以备再次分配使用
ahui5252 2020-12-17
  • 打赏
  • 举报
回复
可以搜下debug模式的malloc,这里有个例子https://blog.csdn.net/bwmwm/article/details/6411236.通常release版的话头部还是有的,但可能尾部越界那部份就没了

65,187

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧