通過一個內存泄露例子體會參數傳遞

程序例子如下:

  1 #include <stdio.h>

  2 #include <stdlib.h>

  3 

  4 void func(int *p , int n)

  5 {

  6     printf("line 6 %p\n",p);

  7     p = malloc(n);

  8     printf("line 8 %p\n",p);

  9     if (p == NULL)

 10         exit(1);

 11     return ;

 12 }

 13 

 14 int main ()

 15 {

 16     int size = 100;

 17     int *p=NULL;

 18     printf("lin 18 %p\n",p);

 19     func(p,size);

 20     printf("line 20  %p\n",p);

 21 

 22     free(p);

 23 

 24     exit(0);

 25 }

  程序的執行過程中,不會報任何錯誤,就是動態申請空間和釋放空間的過程。15行定義了一個指針類型的變量。16,調用了自定義的func函數,並且傳遞參數p和size。問題就是出在參數傳遞上。

   wKiom1aniTzBIMqhAACFbZSO-EQ963.png

   p是一個地址,但是main 函數調用func(p,size)的時候實際進行的傳值調用。所以,在main中釋放p會導致在func子函數中申請的空間無人釋放的問題。

  解決辦法:

  一、採用二級指針的方式。使得main中的p 和 func子函數的中的是同一個地址。

  代碼如下:

  1 #include <stdio.h>

  2 #include <stdlib.h>

  3 

  4 void func(int **p , int n)

  5 {

  6     printf("line 6 %p\n",p);

  7     *p = malloc(n);

  8     printf("line 8 %p\n",p);

  9     if (p == NULL)

 10         exit(1);

 11     return ;

 12 }

 13 

 14 int main ()

 15 {

 16     int size = 100;

 17     int *p=NULL;

 18     printf("lin 18 %p\n",p);

 19     func(&p,size);

 20     printf("line 20  %p\n",p);

 21 

 22     free(p);

 23 

 24     exit(0);

 25 }


  wKioL1ani7TQaXd4AABOr4B9mIw737.png 

   需要深入理解,到底什麼時候二級指針,在本例子中,二級指針可以實現傳遞的p本身而不是副本到func函數中。func函數申請到的100字節的動態內存空間的起始地址就是保存在func和main中的p這個指針變量中。此時在main中free不會導致內存泄露。

  方法二:返回指針的方式:

   

  1 #include <stdio.h>

  2 #include <stdlib.h>

  3 

  4 void * func(int *p , int n)

  5 {

  6     printf("line 6 %p\n",p);

  7     p = malloc(n);

  8     printf("line 8 %p\n",p);

  9     if (p == NULL)

 10         exit(1);

 11     return p ;

 12 }

 13 

 14 int main ()

 15 {

 16     int size = 100;

 17     int *p=NULL;

 18     printf("lin 18 %p\n",p);

 19     p = func(p,size);

 20     printf("line 20  %p\n",p);

 21 

 22     free(p);

 23 

 24     exit(0);

 25 }

  通過返回地址得方式,讓main中p指向100字節的動態內存空間,在main結束的時候,free這100個字節的內存空間,顯然不會導致內存泄露。

  總結:本例子,想從參數傳遞的角度,探討傳值和傳址的不同。對普通變量而言,傳址就是傳遞變量的地址。但是對指針變量要想傳遞地址,就需要使用二級指針。指針是地址不錯,但是存放指針的內存單元也需要有地址。就是傳遞存儲該內存單元地址【也就是二級指針】,就可以實現在主調和被調函數之間使用同一指針操作。  

   

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章