use*_*983 24 c debugging malloc free pointers
为了理解C编程语言中free的用法,我尝试在Ubuntu上运行此代码,但是在运行EXE文件时,我收到了SIGABRT错误.为什么程序没有正常退出?
#include<stdio.h>
#include<stdlib.h>
int main()
{
int ret;
int *ptr;
ptr = (int *)malloc(sizeof(int)*10);
free(ptr);
ptr = &ret;
free(ptr);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
Car*_*rum 38
试图释放你没有得到的指针malloc
(或其中一个朋友)会导致未定义的行为.你的第二次free(ptr)
电话尝试就是这样.
从C规范,§7.22.3.3 free
函数,第2段:
该
free
函数使得指向的空间ptr
被释放,即可用于进一步分配.如果ptr
是空指针,则不执行任何操作.否则,如果参数与先前由内存管理函数返回的指针不匹配,或者如果通过调用free
or 释放了空间realloc
,则行为未定义.
Mah*_*mer 11
ptr = &ret;
free(ptr);
Run Code Online (Sandbox Code Playgroud)
是相同的:
free(&ret);
Run Code Online (Sandbox Code Playgroud)
ret
驻留在堆栈上,而不是堆上.尝试在堆上free()
未分配(使用malloc()
等)的内存将导致未定义的行为.
Ale*_*lex 11
虽然所有未定义的行为答案都是正确的,但查看实现可能会更有帮助.
我认为非常好的参考是K&R C malloc.关于它是如何工作的解释在"The C Programming Langugage",第8.7章中.
请记住,在C语言中查看来自标准库函数的代码时,它们具有实现和规范,其中实现可能具有其规范不需要的可重现行为.
基本上几乎所有malloc
实现都有一个空闲列表,用于管理列表(或多个列表)中的空闲内存区域.自由列表通常以某种方式处理,free
多次调用内存区域会使此列表处于不正确的状态.
当有目的地制作数据结构时,也可以调用恶意行为.Phrack有一篇关于如何free
在破坏freelist 时传递无效内存时调用代码执行的文章.
其他malloc实现也可能值得关注(这是一个不完整的分配库列表).
该功能free()
仅适用于已分配的内存heap
通过malloc()
.不适用于静态分配,因为静态分配是自动处理的.这是错误:
int ret;
ptr = &ret;
free(ptr);
Run Code Online (Sandbox Code Playgroud)
您无法执行此操作,因为ret
未在堆上分配内存.它位于堆栈中,只应释放堆的内存.
ptr = &ret;
free(ptr);
Run Code Online (Sandbox Code Playgroud)
在这里,您尝试释放本地存储堆栈变量的内存.根据规则,你不应该释放它.当main()退出堆栈上的所有本地存储内存时,总是获得空闲.
免费仅适用于堆分配内存.