free()释放了内存为什么还能使用


#include <stdlib.h>
#include <malloc.h>

typedef struct haha {
    int a ;
    long b;
} haha;

int main()
{
    haha **yes = malloc(sizeof(haha *)* 2);

    haha *one = malloc(sizeof(haha)); 
    haha *two = malloc(sizeof(haha));
    one->a = 1;
    one->b = 100;

    two->a = 2;
    two->b = 200;

    yes[0] = one;
    yes[1] = two;

    free(one);
    free(two);

    yes[0]->a= 3;
    yes[1]->a = 4;


}

为什么最后还句不报错?按理来说释放了内存应该不能使用的

这就像你把钱包扔在垃圾桶,五分钟之后你或许还可以找得着,五小时后可能是空瓶子了

malloc是分配一块没用的空间给自己的程序使用,这块空间分配后会标记被使用,free释放的本质就是把这块堆内存还给系统,让其他的程序也能够重新利用这一块空间。这里就涉及到几个问题:

1、free本身不会改变传入的指针指向

2、指针指向的那块内存的内容free不会进行更改

3、如果继续访问这块内存可能还是原来的内容、隔一段时间被其他程序修改后可能会变成其他内容。

4、访问这块内存空间暂时不非法

5、free后可以赋值null来提高程序安全性

因为这个内存还是存在你的内存中的,虽然你释放了,但是你还是可以引用的,这中内存其实是无效的,经常被称为“野指针”,你可以去了解一下

因为这个内存还是存在你的内存中的,虽然你释放了,但是你还是可以引用的,这中内存其实是无效的,经常被称为“野指针”,你可以去了解一下

释放后可以使用,但不是保证总是可以,因为free()后代表以后的malloc()可能会将这块内存区域分配出去。

#include
#include

typedef struct haha {
int a ;
long b;
} haha;

int main()
{
haha **yes = malloc(sizeof(haha ) 2);
haha *one = malloc(sizeof(haha));
haha *two = malloc(sizeof(haha));

//------------------打印地址-----------------//
printf("yes=%p\n",yes);
printf("yes[0]=%p,yes[1]=%p\n",yes[0],yes[1]);
printf("one=%p,two=%p\n",one,two);
printf("*one=%p,*two=%p\n",*one,*two);

yes[0] = one;
yes[1] = two;
free(one);
free(two);

//------------------打印地址-----------------//
printf("----------------释放后-------------\n");
printf("yes=%p\n",yes);
printf("yes[0]=%p,yes[1]=%p\n",yes[0],yes[1]);
printf("one=%p,two=%p\n",one,two);
printf("*one=%p,*two=%p\n",*one,*two);
return 0;

}

图片说明

内存摆着那儿,不管你分配不分配,理论上都是可以用的(因为应用程序操作的内存是虚拟内存(也叫虚拟地址空间),因此有些内存的访问规则是有限制的,访问这些内存一旦违规会导致程序发生虚拟内存违规访问而崩溃),只不过释放后的内存区域可以再分配出去,所以不应该使用。

这个需要理解回收机制。
因为语言不同可能c里面不会太关注回收,因为大神都把这当习惯了,新手根本不会去在意:既然程序可以正常运行,那我回收垃圾干嘛?
先对比一下比较广泛的java,java中如果你给想要让回收的对象赋值null,那么程序就会"记住"你这个操作,之后如果你想使用这个对象的方法,编译器会报错,告诉你使用了未初始化的对象,如果编译器被你代码"骗过",那么执行代码时会抛出空指针异常……
看到了吧,这是编译器做的事儿,或许内存中你要用的数据还存在,但编译器知道那是你放弃的东西就禁止你使用。
而c语言作为低级的面相过程语言,只要没有语法错误,是不会管你干了啥事,不会管你读取内容的地址是否合理(当然const类型的内存是读取不到的),你free的空间,只是告诉系统那内存你不需要了,系统可以在需要内存的时候将其分配给另外的程序或者变量,不过即便它已经被分配出去了,你还是可以读内容,只不过内容代表啥意思你不清楚而已(const地址除外)。
这是c语言比较其他语言的优势,可以直接操作内存,但是!如果你不注意,这会导致程序很危险,万一不小心修改了其他程序的数据,那可能会让程序发生混乱的。