如題所示,咱們主要討論在自定義的內存分配函數中一般見到的代碼以下所示:函數
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; }
結果以下所示:
咱們傳進去的是指針的引用,固然會做用到指針自己。