理解免费的概念

5
尝试了以下代码:
#include<stdio.h>
int main()
{        
        int *p,*q;
        p = (int *)malloc(sizeof(int));
        *p =10;
        q = p;
        printf("%u \n",p);
        printf("%u \n",q);
        free(p);
        printf("%u \n",p);
        return 0;
}

输出结果如下:
[root@lnxdesk Tazim]# ./a.out
154804232
154804232
154804232

即使我已经执行了free(p);,为什么p所在的地址仍然被打印出来呢?free(p)做了什么呢?

我想清楚地理解free/malloc的概念。任何帮助都将是有价值的。

6个回答

5

free()只释放堆上的内存。它不会改变指针的值。如果您尝试打印指针指向的内存,您可能会得到一些垃圾值。

另外,当您调用free时,您传递给它的是指针,而不是指向指针的地址,因此free无法更改您的指针...


没错,但打印指针值仍然是未定义的行为 - http://stackoverflow.com/q/4076563/57428 - sharptooth

3

这是未定义行为 - 一旦你释放了指针,存储的地址就变得无效,你不能对其进行任何操作 - 不仅无法引用它,甚至无法使用printf()输出指针的值。


这并不是技术上的回答该问题。 - JUST MY correct OPINION
@仅是我的正确看法:它确实如此 - 一旦你使用了free(),就不能打印该地址 - 它可能会产生任何结果。 - sharptooth
问题是:“即使我已经使用free(p)释放了p指向的地址,为什么p内部的地址仍然被打印出来?free(p)做了什么?希望能清楚地理解free/malloc的概念。”你没有回答这两个问题的任何一部分。 - JUST MY correct OPINION
@仅代表我的正确观点:UB意味着“任何事情都可能发生”,包括打印先前相同的地址。 - sharptooth
好的,除了那个部分是无意义的。指针永远不会从free()改变 - 你传递的是指针,而不是指针的地址。因此不会发生“任何事情”:指针不能改变。 - JUST MY correct OPINION
显示剩余3条评论

2
你正在打印指针,即为您分配的整数的内存地址。使用free释放内存区域并不会将指针的地址设置为0x00,这可能是你期望的。它只是告诉操作系统该内存区域可以再次被重复利用。
如果你在free(p)之后打印*p,那么你会遇到问题。

你应该编辑你的回答并删除“Printing p is fine ...”,因为它是未定义的行为。 - Jens

1

malloc()及其类似函数会在称为“堆”的内存存储区域中保留空间,并返回指向该保留区域的指针。因此,在上面的示例中,p 可能被赋予一个指向四字节内存区域的指针,该区域已经为其使用保留(本次地址恰好为154804232)。当你执行 *p = 10 时,现在将整数值 10 放入了指向的内存中。当你执行 q = p 时,现在将 q 指向相同的保留堆内存块。

free()及其类似函数只是取消这些内存的保留。当你调用 free() 时,你正在说“我不再使用这些内存”。free() 所做的只是告诉内存管理系统该内存块现在可以再次使用。它绝对不会更改你的指针。 它只是表示该内存块可用。之后你需要确保你不再使用该指针。

如果您再次使用该指针,它可能会正常工作。一次或两次,甚至一千次都没问题,但只要在其他人声称已经释放了该内存块并对其执行某些操作后再次使用它,就会出现问题。那时候,糟糕的事情就会发生<tm>。请不要让坏事发生。

0

记住:指针只是一个地址。在你的malloc或free之前和之后,它将给出相同的结果。malloc()所做的唯一事情就是在该地址处保留空间。free所做的唯一事情就是释放它(很可能将此地址标记为可用于存储其他内容,“清理”需要时间)。 这就是为什么在free之后将指针设置为NULL是一个好主意;因为你可以确定指针是否连接到某些东西。


malloc() 不会在其返回的地址处存储任何内容。 - JUST MY correct OPINION
可能是我的英语太差了。"storing"和"reserving space"之间有什么区别呢? - Raveline
预留空间意味着告诉内存管理系统“不要把这个内存分配给其他任何人”。存储意味着实际将某些值放入该空间。 - JUST MY correct OPINION

0

free不会重新分配指针指向其他内容。实际上,C标准并没有提到需要对指针进行任何操作。在描述中只有以下内容:

free函数会导致由ptr指向的空间被释放,即可用于进一步分配。如果ptr是空指针,则不执行任何操作。否则,如果参数与之前由calloc、malloc或realloc函数返回的指针不匹配,或者该空间已经被free或realloc调用释放,则行为是未定义的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接