1、指针变量作为参数进行值传递给函数的形参,并在堆区(Heap)进行内存分配和赋值
程序源码:
1 #include <stdio.h>
2 #include <stdlib.h>
3
4 void allocation(int *tmp)
5 {
6 tmp = (int *)malloc(sizeof(int));
7 *tmp = 100;
8 }
9
10 int main(void)
11 {
12 int *ptr = NULL;
13 allocation(ptr);
14 printf("*ptr = %d\n", *ptr);
15 return 0;
16 }
结果:
Segmentation fault (core dumped)
分析:
如上图,指针变量ptr进行值传递给函数allocation()的形参tmp并赋值为NULL,这里只是将指针ptr进行值传递即将NULL赋给tmp而不是指向tmp,所以ptr还是指向NULL,然后tmp在堆区(Heap)进行了内存分配并赋值为100,这里分配的堆区的内存地址为0xaabb,由于tmp是局部变量,在第13行执行完allocation()函数后位于栈区的tmp就会自动释放,但是tmp所指向堆区的内存空间0xaabb是不会释放的,只能手动释放(使用free()函数)或者等程序全部运行结束后才会释放,如果不释放的话就会造成内存泄漏,所以*ptr就相当于对野指针NULL进行取值。
2、指针变量先在堆区(Heap)分配内存空间,然后作为参数值传递给函数赋值
程序源码:
1 #include <stdio.h>
2 #include <stdlib.h>
3
4 void allocation(int *tmp)
5 {
6 *tmp = 100;
7 }
8
9 int main(void)
10 {
11 int *ptr = NULL;
12 ptr = (int *)malloc(sizeof(int));
13 allocation(ptr);
14 printf("*ptr = %d\n", *ptr);
15 return 0;
16 }
结果:
*ptr = 100
分析:
如上图,指针变量ptr先在堆区(Heap)进行内存分配,地址为为0xaabb,接着将ptr的值也就是地址0xaabb作为参数进行值传递赋值给tmp,这里tmp也指向了0xaabb并对该地址赋值为100,执行完allocation(ptr)函数后因为tmp是局部变量存在于栈区,所以tmp就会自动释放内存,但是ptr依旧指向0xaabb,此时打印*ptr时由于之前tmp对ptr所指向的地址0xaab已经赋值为100了,所以*ptr就等于100。
3、在函数里对局部变量进行堆区(Heap)的内存分配和赋值,并返回该堆区空间的地址
程序源码:
1 #include <stdio.h>
2 #include <stdlib.h>
3
4 int *allocation(void)
5 {
6 int *tmp = NULL;
7 tmp = (int *)malloc(sizeof(int));
8 *tmp = 100;
9 return tmp;
10 }
11
12 int main(void)
13 {
14 int *ptr = NULL;
15 ptr = allocation();
16 printf("*ptr = %d\n", *ptr);
17 if(ptr != NULL)
18 {
19 free(ptr);
20 ptr = NULL;
21 }
22 return 0;
23 }
结果:
*ptr = 100
分析:
如上图,在allocation()函数对局部变量tmp进行了堆区的内存分配并赋值为100,该地址为0xaabb,接着将地址0xaabb返回给主函数里面的指针变量ptr即ptr = allocation(),这里ptr也就指向了0xaabb,由于tmp是局部变量位于栈区,当该函数执行完之后tmp就会被自动释放,所以打印的时候ptr依旧指向0xaabb,值为100,接着将指针变量ptr所指向的堆区内存空间给释放掉(使用free()函数),释放后ptr还是指向0xaabb,所以要让ptr等于NULL。