1.会产生野指针的做法
#include <stdio.h> //这就是一种错误的写法 int main(){ int *p = NULL; p = (int *)malloc(4); //释放P所指向的内存空间,但指针变量p仍然留在栈中,成为了野指针 if (p != NULL){ free(p); } if (p != NULL){ free(p); } return 0; }
2.正确的做法:
#include <stdio.h>//指针变量和指针所指向的内存变量是两个不同的概念 //使用动态内存分为三步 //1.定义时,将指针为定义NULL //2.释放内存时,把指针变量重新赋值或者NULL //3.释放内存后,把指针变量赋值为NULL int main02() { int *p = NULL; p = (int *)malloc(4); //这才是正确的写法 if (p != NULL){ free(p);//释放P所指向的内存空间,但指针变量p仍然留在栈中,成为了野指针 p = NULL;//释放野指针 } return 0; }
3.间接赋值是指针存在的最大意义
间接赋值的条件:
(1)定义实参(普通变量)和形参(指针变量)
(2)把实参的地址传给形参
(3)利用形参来修改实参的值
被调用函数分配的内存,结果传出来的两种方法
(1)return
(2)指针做函数参数
//这种方式是通过return将函数分配的内存传给被调用函数
char *getBuf() { char *p = NULL; p = (char *)malloc(100); strcpy(p, "zhanghanzhi"); return p; }
//这种方式是通过指针作为函数参数间接赋值 void getBuf(char *p) { char tmp = NULL; tmp = (char *)malloc(100); strcpy(tmp, "zhanghanzhi"); p = tmp; } int main() { //1.定义实参(普通变量)和形参(指针变量) char *p; //2.把实参的地址传给形参 //3.利用形参来修改实参的值 getBuf(p); return 0; }
4.几个本质
数据类型:数据类型的本质是固定大小内存的别名。对变量声明数据类型,是为了告诉编译器分配几个字节的内存。
变量:变量的本质是一段内存空间的别名。也就是给一段内存空间取一个新的名字,就是变量。
指针:指针也是一种数据类型,它的值是某一个内存空间的地址。指针的步长根据它指向的内存空间的数据类型而定。
*p在等号左边是对p所指向的内存空间赋值;*p放在等号的右边是对p所指向的内存空间取值。
数组中[]的本质:假如有数组array,则array[i]等价于*(array+i),是因为[]对于程序员来讲是友好的,但是编译器最终还是要将它理解为指针,也就是数组作为函数参数时的退化。array[i] ==> array[0+i] ==>*(array+i)