#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语言比较其他语言的优势,可以直接操作内存,但是!如果你不注意,这会导致程序很危险,万一不小心修改了其他程序的数据,那可能会让程序发生混乱的。