2013-03-01 24 views
1
char **test() 
{ 
    char *a[3]; 
    a[0] = (char *) malloc(sizeof(char) *3); 
    a[1] = (char *) malloc(sizeof(char) *3); 
    a[0] = "aa"; 
    a[1] = "bb"; 
    return a; 
} 

//main 
try{ 
    char ** a; 
    a = test(); 
    cout << a[0] << " " << a[1]; 
} 
catch(std::exception){} 

在VS2008編譯的,這個計劃沒能輸出「BB」,但之後我刪除了try catch塊,它竟然是「AA BB」,這是真正。原因和解決方案?嘗試捕捉在焦炭的影響**返回值

+2

除此之外,有沒有一個具體的點到這一點(或者也許我只是錯過了一次,我看到了那些)。?你正在返回一個局部變量的地址,當你在你的主體中評估一個[]時,這個變量超出了範圍。不知道這是你的意圖,但它是**未定義的行爲**。 – WhozCraig 2013-03-01 17:28:39

+0

爲什麼我們在C++中使用malloc? – andre 2013-03-01 17:30:43

+0

@andre,因爲他可以和''不會拋出一個'#錯誤'作爲宏替換(當然)。 – WhozCraig 2013-03-01 17:31:38

回答

3

該程序有未定義的行爲,因爲你正在返回一個指向本地的指針。您需要將a陣列malloc爲了分配來解決這個問題:

char **test() { 
    char **a = (char**)malloc(sizeof(char*) * 2); 
    a[0] = (char *) malloc(sizeof(char) *3); 
    a[1] = (char *) malloc(sizeof(char) *3); 
    strcpy(a[0], "aa"); 
    strcpy(a[1], "bb"); 
    return a; 
} 

當然現在的你釋放所有malloc -ed內存在main,以避免內存泄漏承擔全部責任(你已經在你的實現中用鉤子表示;現在你只需要添加第三個free給調用者)。

您看到的差異很可能是由於堆棧管理有區別,無法使用try/catch塊。看起來,如果沒有try/catch,本地數據仍然可供您打印,即使返回test()函數後引用該數據不再合法。

+0

+1(就像你沒有看到*即將到來)。 – WhozCraig 2013-03-01 17:32:10

+1

我寧願看到不引入第三次內存泄漏的解決方案;但解釋眼前的問題+1。 – 2013-03-01 17:32:59

+1

LOL內存泄漏仍然有效並且完全不變= P – WhozCraig 2013-03-01 17:33:15

0

問題1:返回一個指向本地數組的指針。這在函數返回時被銷燬,並且在那之後使用指針給出未定義的行爲。

問題2:顯式內存管理,並用指向字符串文字的指針覆蓋分配內存的指針。你分配的內存被泄漏;如果你嘗試修改文字,你會得到更多未定義的行爲。

假設你正在寫C++,不C,下面將解決這兩個問題:

std::vector<std::string> test() {return {"aa", "bb"};} 
從內存泄漏