zoukankan      html  css  js  c++  java
  • C++ 有关指针作为函数参数的问题,自定义内存分配函数传递二级指针的问题

    如题所示,我们主要讨论在自定义的内存分配函数中通常见到的代码如下所示:

    void Create(A** addr);

    其中传递的参数是二级指针。为什么?

    我们先看一下完整的动态内存分配函数的简单例子:

    struct A {
      int a = 0;
      int b = 0;
      int c[3];
    };
    
    void Create(A** addr) {
      printf("a1: %p
    ", addr);
      *addr = new A();
      printf("a2: %p
    ", addr);
    }
    
    
    
    int main() {
     A *a;
     printf("a0: %p
    ", a);
     Create(&a); // 传递二级指针值
     printf("a4: %p
    ", a);
      return 0;
    }
    

    我们看下函数运行结果:

    我们看到传进去的*a的值改变了,而且这个改变作用到了*a本身

    在看下我们一般情况下想到的分配方式:

    struct A {
      int a = 0;
      int b = 0;
      int c[3];
    };
    
    void Create(A* addr) {
      printf("a1: %p
    ", addr);
      addr = new A();
      printf("a2: %p
    ", addr);
    }
    
    
    
    int main() {
     A *a = nullptr;
     printf("a0: %p
    ", a);
     Create(a); 传进去指针本身
     printf("a4: %p
    ", a);
      return 0;
    }
    

    同时我们在看下结果:

    我们看到对指针的操作,并没有作用到指针本身。这是因为哪怕我们传进去的是个指针,但是还是以值传递的方式传递指针的值。

    具体的过程是,我们在*a传递到函数里面时,函数自身创建了一个中间变量,我们姑且称他为temp,这个temp的值为 a,我们后面进行new之后也只是简单的将

    分配后的内存地址给了temp,所以才会出现上面结果。

    但是对于二级指针而言,传进去的是指针的地址,对指针地址所指值进行操作,当然会改变指针本身的值。

    其实该种方式也可以等价于:

    struct A {
      int a = 0;
      int b = 0;
      int c[3];
    };
    
    void Create(A* &addr) {
      printf("a1: %p
    ", addr);
      addr = new A();
      printf("a2: %p
    ", addr);
    }
    
    
    
    int main() {
     A *a;
     printf("a0: %p
    ", a);
     Create(a);
     printf("a4: %p
    ", a);
      return 0;
    }
    
    

    结果如下所示:

    我们传进去的是指针的引用,当然会作用到指针本身。

  • 相关阅读:
    va_list/va_start/va_arg/va_end深入分析【转】
    Linux Kernel中断子系统来龙去脉浅析【转】
    Linux系统调用---同步IO: sync、fsync与fdatasync【转】
    Linux中变量#,#,@,0,0,1,2,2,*,$$,$?的含义【转】
    linux下的module_param()解释【转】
    Makefile 使用总结【转】
    FLASH的知识【转】
    Linux MTD系统剖析【转】
    linux的mtd架构分析【转】
    linux设备树笔记__dts基本概念及语法【转】
  • 原文地址:https://www.cnblogs.com/Smarc/p/14110878.html
Copyright © 2011-2022 走看看