如题所示,咱们主要讨论在自定义的内存分配函数中一般见到的代码以下所示:函数
void Create(A** addr);
指针
其中传递的参数是二级指针。为何?code
咱们先看一下完整的动态内存分配函数的简单例子:blog
struct A { int a = 0; int b = 0; int c[3]; }; void Create(A** addr) { printf("a1: %p\n", addr); *addr = new A(); printf("a2: %p\n", addr); } int main() { A *a; printf("a0: %p\n", a); Create(&a); // 传递二级指针值 printf("a4: %p\n", a); return 0; }
咱们看下函数运行结果:
内存
咱们看到传进去的*a
的值改变了,并且这个改变做用到了*a
自己变量
在看下咱们通常状况下想到的分配方式:引用
struct A { int a = 0; int b = 0; int c[3]; }; void Create(A* addr) { printf("a1: %p\n", addr); addr = new A(); printf("a2: %p\n", addr); } int main() { A *a = nullptr; printf("a0: %p\n", a); Create(a); 传进去指针自己 printf("a4: %p\n", a); return 0; }
同时咱们在看下结果:
im
咱们看到对指针的操做,并无做用到指针自己。这是由于哪怕咱们传进去的是个指针,可是仍是以值传递的方式传递指针的值。d3
具体的过程是,咱们在*a
传递到函数里面时,函数自身建立了一个中间变量,咱们姑且称他为temp
,这个temp的值为 a
,咱们后面进行new
以后也只是简单的将内存分配
分配后的内存地址给了temp,因此才会出现上面结果。
可是对于二级指针而言,传进去的是指针的地址,对指针地址所指值进行操做,固然会改变指针自己的值。
其实该种方式也能够等价于:
struct A { int a = 0; int b = 0; int c[3]; }; void Create(A* &addr) { printf("a1: %p\n", addr); addr = new A(); printf("a2: %p\n", addr); } int main() { A *a; printf("a0: %p\n", a); Create(a); printf("a4: %p\n", a); return 0; }
结果以下所示:
咱们传进去的是指针的引用,固然会做用到指针自己。