C内存管理,具有指向同一位置的更多指针



我玩的是这个代码:

#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("%cn", i[0]);
return 0;
}

我本以为会得到一个错误,但它却打印了"a",如果"a"被取消分配,为什么要打印它?如果main(),函数(int*p)中发生的事情会有什么影响?(如果可以的话,解释一下"p"指针发生了什么)

假设我在同一个函数中有这两个:

int *a = malloc(...);
int *b = a;

它们都指向同一段记忆,但当我必须释放它时,我应该对它们两个调用free,还是只调用其中一个?(如果可能的话,再次解释原因)

这是未定义的行为。释放指针只是告诉操作系统分配的内存可以被重写。记忆还在。。因为没有更好的词。但是任何事情都有可能发生。。它现在可能会为您打印一个,其他时候可能是另一个字符或数字,因为另一个程序已写入该内存位置。。。任何事情都有可能发生。

关于你的最后一个问题。。a和b只是地址的象征性名称。免费拨打地址是很重要的,所以无论你是拨打free(a)还是拨打free(b),你都很棒。

您已经将内存返回到堆中,但尚未重用内存。所以,有时内存内容保持不变,你可以读写它,就好像它还在使用一样。

但您永远不应该使用已经释放的内存,因为无法保证内存以这种方式保持多久。

在第二部分a = malloc(...); b = a中,两个变量都指向相同的内存。由于这只是一个字节,您必须free()它恰好。否则,您将有一个双空闲,这可能会损坏堆。

为@SSH更新他提出的问题:

free(a)只将内存返回给堆。它不修改ab。无论内存是否已释放,检查if(a)if(b)的结果都为true。只有当您将ab设置为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 */
}

它打印‘a’是因为你很幸运。这是未定义的行为。它当前被"取消分配",这意味着它(内存位置)被标记为"覆盖">

您的代码是错误的,但得到错误意味着有人在检查它是否错误。在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== 

最新更新