我正在玩这段代码:
#include <stdlib.h>
#include <stdio.h>
void function(int *p){
free(p);
}
int main(){
int *i = calloc(3, sizeof(int));
function(i);
i[0] = 'a';
printf("%c\n", i[0]);
return 0;
}
我预计会收到一个错误,但是它会打印'a',如果'a'被解除分配,为什么要打印它?函数(int * p)中发生的事情有什么影响,如果main()?(如果可以,解释那个'p'指针发生了什么)
假设我在同一个函数中有这两个:
int *a = malloc(...);
int *b = a;
他们两个都指向同一块记忆,但是当我必须释放它时,我应该在它们两个上免费打电话,还是只打电话给其中一个?(再次解释为什么可能)
答案 0 :(得分:5)
这是未定义的行为。释放指针只是告诉操作系统可以覆盖分配的内存。由于缺乏更好的词,记忆依旧存在。但是任何事情都可能发生..它现在可能会为你打印,有时它可能是另一个字符或数字,因为另一个程序已写入该存储位置......任何事情都可能发生。
对于你的上一个问题.. a和b只是一个地址的符号名称。在地址上免费拨打电话非常重要,因此无论您是free(a)
还是free(b)
,您都很棒。
答案 1 :(得分:3)
它打印'a'因为你很幸运。这是未定义的行为。它目前被“取消分配”,这意味着它(内存位置)被标记为“覆盖”
答案 2 :(得分:3)
您已将内存返回堆中,但内存尚未重用。因此,有时内存内容保持不变,您可以读取和写入它,就像它仍在使用中一样。
但是你永远不应该使用已经释放的内存,因为无法保证内存保持多久。
在你的第二部分a = malloc(...); b = a
中,两个变量都指向同一个内存。由于这只是一个字节,因此您必须free()
完全一次。否则你有一个双重免费,这可能会破坏堆。
更新:
free(a)
仅将内存返回堆中。它不会修改a
或b
。无论是否释放内存,检查if(a)
或if(b)
的计算结果为true。只有当您将a
或b
设置为null时,检查才会评估为false,无论内存是否已释放。
因此free(a)
和if(a)
是独立的操作。他们互不影响。
a = malloc(10); /* assuming malloc doesn't return NULL */
if (a) {
/* will be true, memory is NOT freed */
}
free(a);
if (a) {
/* will be true, although memory is freed */
}
a = malloc(10); /* assuming malloc doesn't return NULL */
a = NULL;
if (a) {
/* will NOT be true, although memory is NOT freed */
}
答案 3 :(得分:2)
您的代码错误,但是收到错误意味着某些内容正在检查它是错误的。 C中有很多东西可以做错,但从未检查过。这通常是因为执行检查会有性能损失,或者检查它是一件非常困难的事情。访问已释放的内存就是其中之一。通过像valgrind这样的工具运行程序会报告更多这类问题,但程序运行速度会慢得多。
以下是valgrind的输出:
==19080== Invalid write of size 4
==19080== at 0x8048468: main (main.c:11)
==19080== Address 0x403b028 is 0 bytes inside a block of size 12 free'd
==19080== at 0x4006EED: free (vg_replace_malloc.c:366)
==19080== by 0x8048434: function (main.c:5)
==19080== by 0x8048463: main (main.c:10)
==19080==
==19080== Invalid read of size 4
==19080== at 0x8048472: main (main.c:12)
==19080== Address 0x403b028 is 0 bytes inside a block of size 12 free'd
==19080== at 0x4006EED: free (vg_replace_malloc.c:366)
==19080== by 0x8048434: function (main.c:5)
==19080== by 0x8048463: main (main.c:10)
==19080==