1. 程式人生 > >C++指標引數傳遞記憶體 及 在函式中用指標new的一個空間

C++指標引數傳遞記憶體 及 在函式中用指標new的一個空間

通過幾個例子說明C++指標引數傳遞記憶體的問題

例子一:

void GetMemory(char* p, int num)

{

p = (char*)malloc( sizeof(char) * num );

return;

}

int main(void)

{

char* str = NULL;

GetMemory(str, 30);

std::cout << str << std::endl; // str 仍為NULL

}

分析: 如果函式引數是一個指標,不要指望用該指標去申請動態記憶體。例子一中,main函式呼叫 GetMemoty(str,30) , 並沒有使str獲得期望的記憶體,str依舊為NULL。毛病出在GetMemory函式中, 編譯器總是要為函式的每個引數製作臨時副本,指標引數p的副本是 _p,編譯器使_p = p。如果函式內的程式修改了_p的內容,就導致引數p的內容作了相應的修改。這就是指標可以用作輸出引數的原因。在例一中,_p申請了新的記憶體,只是把_p所指記憶體地址改變了,但是p絲毫未變。所以函式GetMemory並不能輸出任何東西。事實上,每執行一次GetMemory就會洩漏一塊記憶體,因為沒有free釋放記憶體。如果非要用指標引數去申請記憶體,那麼應該改用“指向指標的指標”,具體見例子二。

例子二:

void GetMemory_2(char** p, int num)

{

*p = (char*)malloc( sizeof(char) * num );

return;

}

int main(void)

{

char* str = NULL;

GetMemory_2(&str, 30);

strcpy(str, "hello world");

std::cout << str << std::endl;

free(str);

}

分析: GetMemory_2 函式引數 *p的臨時副本是 _*p, 在函式中,申請了一塊新的記憶體,相當於改變了指標_*p的內容,從而指標*p的內容也改變了,所以記憶體申請成功了。

對於二級指標,做形參時傳入地址(注意此時傳入的是二級指標的地址),如果改變該二級指標地址(**p),對該指標的操作也將無效,但是改變二級指標的內容(例如*p),則該二級指標可以正常返回。

補充二級指標:

int a = 10;

int *p = &a;

int **p = &p;

*p為a      (&a為p)

*p為p      (&p為pp)

**p為a