函式引數的傳遞問題(指標的指標)

2022-03-03 06:44:42 字數 3711 閱讀 3709

程式1

void mymalloc(char *s) //我想在函式中分配記憶體,再返回

s=(char *) malloc(100);

void main()

char *p=null;

mymalloc(p); //這裡的p實際還是null,p的值沒有改變,為什麼?

if(p) free(p);

程式2

void mymalloc(char **s)

*s=(char *) malloc(100);

void main()

char *p=null;

mymalloc(&p); //這裡的p可以得到正確的值了

if(p) free(p);

程式3

#include using

namespace

std;

void fun(int *p)

main()

結果:

程式4

#include using

namespace

std;

void fun(int *p)

main()

結果為

為什麼?

1.被分配記憶體的是形參s,p沒有分配記憶體;

2.被分配記憶體的是形參s指向的指標p,所以分配了記憶體。

不是指標沒明白,是函式呼叫的問題!看看這段:

程式5指標引數是如何傳遞記憶體的?

如果函式的引數是乙個指標,不要指望用該指標去申請動態記憶體。程式5中,test函式的語句getmemory(str, 200)並沒有使str獲得期望的記憶體,str依舊是null,為什麼?

#include using

namespace

std;

void getmemory1(char *p, int

num)

intmain()

程式5試圖用指標引數申請動態記憶體毛病出在函式getmemory中。編譯器總是要為函式的每個引數製作臨時副本,指標引數p的副本是 _p,編譯器使 _p = p。如果函式體內的程式修改了_p的內容,就導致引數p的內容作相應的修改。這就是指標可以用作輸出引數的原因。在本例中,_p申請了新的記憶體,只是把_p所指的記憶體位址改變了,但是p絲毫未變。所以函式getmemory並不能輸出任何東西。事實上,每執行一次getmemory就會洩露一塊記憶體,因為沒有用free釋放記憶體。

如果非得要用指標引數去申請記憶體,那麼應該改用「指向指標的指標」,見程式6

#include using

namespace

std;

void getmemory2(char **p, int

num)

intmain()

程式6用指向指標的指標申請動態記憶體由於「指向指標的指標」這個概念不容易理解,我們可以用函式返回值來傳遞動態記憶體。這種方法更加簡單,見示例7-4-3。

#include using

namespace

std;

char *getmemory3(int

num)

intmain()

程式7用函式返回值來傳遞動態記憶體用函式返回值來傳遞動態記憶體這種方法雖然好用,但是常常有人把return語句用錯了。這裡強調不要用return語句返回指向「棧記憶體」的指標,因為該內存在函式結束時自動消亡,見程式8。

#include using

namespace

std;

char *getstring(void

)int

main()

結果:

程式8 return語句返回指向「棧記憶體」的指標

用偵錯程式逐步跟蹤主函式,發現執行str = getstring語句後str不再是null指標,但是str的內容不是「hello world」而是垃圾。

如果把示例程式7改寫成程式8,會怎麼樣?

#include using

namespace

std;

char *getstring2(void

)int

main()

程式8 return語句返回常量字串函式程式8執行雖然不會出錯,但是函式getstring2的設計概念卻是錯誤的。因為getstring2內的「hello world」是常量字串,位於靜態儲存區,它在程式生命期內恆定不變。無論什麼時候呼叫getstring2,它返回的始終是同乙個「唯讀」的記憶體塊。

看看林銳的《高質量的c/c++程式設計》,上面講得很清楚的

對於1和2:

如果傳入的是一級指標s的話,

那麼函式中將使用的是s的拷貝,

要改變s的值,只能傳入指向s的指標,即二級指標

程式1:

void mymalloc(char *s) //我想在函式中分配記憶體,再返回

s=(char *) malloc(100); // s是值參, 函式返回後就回覆傳遞前的數值,無法帶回分配的結果

這個和呼叫 void func (int i) ; 一樣,退出函式體,i指復原的

程式2:void mymalloc(char **s)

*s=(char *) malloc(100); // 這個是可以的

等價於void int func(int * pi) pi指標不變,指標指向的資料內容是變化的

值參本身不變,但是值參指向的記憶體的內容發生了變化。

程式3:

void fun(int *p)

int b=100;

p=&b;       // 等同於第乙個問題, b的位址並沒有被返回

程式4:

void fun(int *p)

*p=100; // okay

結論:

1.       函式的返回值是指標型別的,檢查是靜態記憶體指標還是堆記憶體指標還是棧記憶體指標,棧記憶體指標是絕對要不得滴!

2.       函式需要使用指標引數進行傳入傳出的,在函式中只能對指標的指向的值(*p)進行修改,而不能修改指標指向,也就是指標位址!(函式中不得修改指標引數的位址,否則請使用指標的指標!)

參考資料:

函式的指標引數傳遞問題 理解指標變數

我們預期的結果是輸出兩個 a.可是執行的結果卻是下圖。為什麼只輸出了乙個a?下面我們分析一下 在fun1中,我們用malloc分配了一段記憶體,並將該段記憶體的首位址放在指標變數n,然後我們就用n這個位址,開始給結構體賦值。在fun2中,我們以為在fun1中已經給node分配好了記憶體,也賦好值了。...

指標引數傳遞的問題

內容如下 1 指標作為引數傳遞進去的僅僅只是指標的值,而不是指標的位址,或者說只是指標的乙份拷貝,例如 void pointer int p intmain the p is0xbfd46498 addr is 1076599652,p is 22the p is0xbfd46498 addr is...

指標作為函式的引數傳遞的問題

如果乙個函式的引數是乙個指標,不能用此指標去動態申請記憶體 include include using namespace std void getmemory char p,int size void test int main void 傳送錯誤是因為 getmemory 函式中申請記憶體的時候...