C++指標引數傳遞記憶體 及 在函式中用指標new的一個空間
阿新 • • 發佈:2019-01-28
通過幾個例子說明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