動態申請內存

http://blog.sina.com.cn/s/blog_590be5290100hvo4.html

如果函數的參數是一個指針,不要指望用該指針去申請動態內存。示例1中,Test函數的語句GetMemory(str, 100)並沒有使str獲得期望的內存,str依舊是NULL,爲什麼? 

void GetMemory(char *p, int num)

{

    p = new char[num];

}

void Test(void)

{

    char *str = NULL;

    GetMemory(str, 100);    // str 仍然爲 NULL 

    strcpy(str, "hello");   // 運行錯誤

    delete(str); 

}

                    示例1  試圖用指針參數申請動態內存  

 

毛病出在函數GetMemory中。編譯器總是要爲函數的每個參數製作臨時副本,指針參數p的副本是 _p,編譯器使 _p = p。如果函數體內的程序修改了_p的內容,就導致參數p的內容作相應的修改。這就是指針可以用作輸出參數的原因。在本例中,_p申請了新的內存,只是把_p所指的內存地址改變了,但是p絲毫未變。所以函數GetMemory並不能輸出任何東西。事實上,每執行一次GetMemory就會泄露一塊內存,因爲沒有用free釋放內存。

 

如果非得要用指針參數去申請內存,有兩種方法:

1.指向指針的指針,見示例 2 

void GetMemory2(char **p, int num)

{

    *p = new char[num];

}

void Test2(void)

{

    char *str = NULL;

    GetMemory2(&str, 100);  // 注意參數是 &str,而不是str

    strcpy(str, "hello");  

    cout<< str << endl;

    delete(str); 

}

示例2    用指向指針的指針申請動態內存

 

2.由於“指向指針的指針”這個概念不容易理解,我們可以用函數返回值來傳遞動態內存。這種方法更加簡單,見示例3 

char *GetMemory3(int num)

{

    char *p = new char[num];

    return p;

}

void Test3(void)

{

    char *str = NULL;

    str = GetMemory3(100); 

    strcpy(str, "hello");

    cout<< str << endl;

    delete(str); 

}

示例  用函數返回值來傳遞動態內存 

 

3.示例2中,申請內存與賦值的操作在不同函數中。如果要將兩者放在同一函數中,應如何處理?見示例4 

void GetMemory2(char **p, int num)

{

     *p = new char[num];
     char* str = *p;
     strcpy(str, "hello");

}

void Test2(void)

{

    char *str = NULL;

    GetMemory2(&str, 100);  // 注意參數是 &str,而不是str

    cout<< str << endl;

    delete(str); 

}

示例4   申請內存的同時進行賦值 


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