【c++】指針參數是如何傳遞內存的

參數策略ios

若是函數的參數是一個指針,不要期望用該指針去動態申請內存。以下:數組

void GetMemory(char *p, int num)
{
    p = (char *)malloc(sizeof(char) * num);
}
void Test(void)
{
    char *str = NULL;
    GetMemory(str, 100);     //str仍未NULL
    strcpy(str, "hello");    //運行錯誤
}

緣由是編譯器老是爲每一個參數製做臨時副本。指針參數p, 其副本爲_p,使_p=p。若是改變了_p所指的內容,相應的p所指的內容也跟着改變(畢竟指向一樣的地方)。可是在GetMemory中動態分配內存空間,改變了_p的內容。在調用函數中的p仍是指向NULL。再者,由於函數GetMemory中動態分配了空間,可是沒釋放,這樣調用一次函數,就泄露了一次內存。圖示:
函數

若是非得用指針參數申請內存,能夠用指針的指針做爲參數申請內存spa

void GetMemory(char **p, int num)
{
    *p = (char *)malloc(sizeof(char) * num);
}
void Test(void)
{
    char *str = NULL;
    GetMemory(&str, 100);     //記得加地址符
strcpy(str, "hello");
free(str) }

原理是同樣的,比較難理解,圖示表示:
指針

比較好的方法是傳指針的引用code

#include <iostream>
#include <string>
#include <cstring>
#include <cstdlib>
using namespace std;
void GetMemory(char *&p, int num)
{
    p = (char *)malloc(sizeof(char) * num);
}

void Test(void)
{
    char *str = NULL;
    GetMemory(str, 100);
    strcpy(str, "hello");
    cout << str << endl;
    free(str);
}
int main()
{
    Test();
}

 這裏注意指針的引用 爲char* &a,要是很差理解能夠這樣:blog

    typedef char* pchar;
    pchar &a

返回值策略內存

能夠用函數返回值來傳遞動態內存。這中方法比「指針的指針」簡單多了編譯器

char *GetMemory(int num)
{
     char *p = (char *)malloc(sizeof(char) * num);
     return p;
}
void Test(void)
{
    char *str = NULL;
    str = GetMemory(100);  //str指向了動態分配的空間
    strcpy(str, "hello"); 
    free(str)
 }

在使用返回值時,千萬別返回指向「棧內存」的指針、引用,由於該內存在函數結束時自動消亡了,返回的指針是個野指針了。例如string

char *GetString()
{
     char p[] = "hello world"; //數組內容存儲在棧區,函數結束時,會釋放掉
     return p;
}
void Test(void)
{
    char *str = NULL;
    str = GetString();      //由於非配的內存早已釋放掉,此時的str是個野指針,內容是垃圾
   cout << str << endl;
 }

在函數中不定義數組,定義指針,示例:

char *GetString()
{
     char *p = "hello world"; //數組內容存儲在靜態區,函數結束時,不會釋放掉
     return p;
}
void Test(void)
{
    char *str = NULL;
    str = GetString();      
    cout << str << endl;
 }

此時的程序是正確的,可是有一點,此時分配的內存處於靜態區,是隻能夠讀取可是不能夠修改的。

相關文章
相關標籤/搜索