1.函数内引用

代码如下:

#include <stdio.h>

void main(void) {

    int *point = NULL;
    int* *point0 = NULL;
    int tmp = 965042717;

    point = &tmp;
    point0 = &point;

    printf("%d", *(*point0));

    return 0;
}

上面源码可知,point是基础指针,point0是二级指针.

由于二级指针的特性(指向指针的指针),因此point0=&point的赋值是合法的.

通过上图可知在栈帧内,二级指针与基础指针的区别是二级指针指向的是基础指针的地址。

通常想要得到基础指针所指向地址的值是需要用 *解引的.

例如:printf("%d",*point);就可以得到tmp的值,因为上图中point是指向tmp的地址0x9a4e.

对于二级指针point0来说,若是想要操作tmp变量,就避免不了基础指针point.

解引方式为:*(*point0).分析如下:

   *point0内部存放的是 0xf72c,所以解引出来的是point的值 0x9a4e,因此还需要再加一个 * 进一步解引.

  *(*point0) 也可以换算为 *(0x9a4e).

  *(0x9a4e) 也就是等于 *point.所以就可以操作到tmp变量了.

2.跨函数动态内存分配的引用方法

如果指针跨函数无返回值传参并且动态内存分配的话,就需要用到二级指针来防止内存泄露.

#include <stdio.h>

void test(int* *p) {
    *p = (int*)malloc(sizeof(int));
    *(*p)=518;
}

void main(void) {
    int *point = NULL;

    test(&point);
    printf("%d", *point);

    return 0;
}

通过以上代码分析可得:

  由于p指针指向的是point的地址,因此*p = (int*)malloc(sizeof(int));函数是给point指针分配的堆内存.

  所以在赋值的时候就把数据写入了point指针指向的地址中.

  即使test函数栈帧释放了,p指针没了,point依然指向堆地址.

通过上图可知,二级指针依然是通过解引基础指针分配内存并且再次解引来赋值操作.

如果用基础指针来跨函数操作的话,会造成内存泄露的现象发生,解析:

   如果p是基础指针,那么p指向的地址也是point指向的地址.

   通过malloc函数分配内存后p指针所指向的就是新的堆地址.

   那么,函数结束后p指针被结束,p指针所指向的堆地址没有被回收也没有被利用.


分享知识使我感到充实而快乐!