#include <stdio.h>
#include <stdlib.h> //malloc的头文件
int main(){
int *p = NULL; //在栈区定义一个指针变量p,指向NULL
//1 在堆区动态分配一个int(4个字节)的空间,用指针p指向这个空间的首地址
p =(int*)malloc(sizeof(int)); //因为malloc的返回值是void*,这里需要强制转换以下,转成int*
printf("%p\n",p); //查看在堆区申请的空间的首地址
//2 判断地址分配成功没有
if(p==NULL){
printf("malloc failed!\n");
//这里用到了调试宏
//__FILE__:文件的名字
//__func__:函数的名字
//__LINE__:行号
printf("%s:%s:%d\n",__FILE__,__func__,__LINE__);
return -1;
}else{
printf("malloc succcss!\n");
printf("%s:%s:%d\n",__FILE__,__func__,__LINE__);
}
*p = 100;
printf("%d\n",*p);
//3 释放空间
free(p); //从首地址开始
//4 指针置为NULL
p = NULL;
//最后一步非常的重要,一定要把指针置为NULL,否则后面的p虽然被释放了,但是还可以操作堆里面的数据,虽然是非法的,下面是程序的验证。
printf("%p\n",p); //看看释放之后p的地址有没有变化
//结论:虽然释放了但是p还是指向堆区的首地址。这时为了避免野指针应该把p=NULL
//继续验证
printf("%d\n",*p);//猜想:此时应该不能读取堆区的值100了
//结论:是的,不是100了,应该是一个随机的值,大多数情况是0
int *q = NULL;
q = (int*)malloc(sizeof(int));
printf("%p\n",q);//检查看看释放之后q还能不能得到原来的地址
//又把刚才p分配的地址分给了q,现在的话p和q指向相同的地址
*q = 200;
printf("%d\n",*q);
*p = 300; //注意此时的p地址和堆区的地址一样,但是此时操作的是栈区的内存。
printf("%d\n",*q);
printf("%d\n",*p);
return 0;
}