2010-11-13 136 views
0

我編譯代碼時沒有收到錯誤信息,但我無法獲得正確的結果。如何從函數返回數組?

#include <iostream> 
using namespace std; 

struct Coord{ 
int r; 
int c; 
}; 
struct CoordwValue{ 
Coord C; 
char Value; 
}; 

CoordwValue* getNeighbors(); 

int main(){ 
CoordwValue *k= getNeighbors(); 
for (int i=0;i<4;i++) 
    cout<<(k[i].Value); 
} 
CoordwValue *getNeighbors(){ 
CoordwValue Neighbors[4]; 
Neighbors->Value='X'; 
Neighbors->C.r= 0; 
Neighbors->C.c= 1; 
(Neighbors+1)->Value='0'; 
(Neighbors+1)->C.r= 1; 
(Neighbors+1)->C.c= 2; 
(Neighbors+2)->Value='1'; 
(Neighbors+2)->C.r= 2; 
(Neighbors+2)->C.c= 1; 
(Neighbors+3)->Value='X'; 
(Neighbors+3)->C.r= 1; 
(Neighbors+3)->C.c= 0; 
//for (int i=0;i<4;i++) 
// cout<<Neighbors[i].Value; 
return Neighbors; 
} 

代碼打印這部分X01X

for (int i=0;i<4;i++) 
    cout<<Neighbors[i].Value; 

但我不能得到

for (int i=0;i<4;i++) 
    cout<<(k[i].Value); 

什麼問題同樣的結果?

編輯:

此版本的代碼工作正常。

#include <iostream> 
using namespace std; 


char* getNeighbors(); 

int main(){ 
    char *k= getNeighbors(); 
    for (int i=0;i<4;i++) 
     cout<<(*(k+i)); 
} 
char *getNeighbors(Coord C, int r){ 
    char Neighbors[4]; 
    *Neighbors='X'; 
    *(Neighbors+1)='0'; 
    *(Neighbors+2)='1'; 
    *(Neighbors+3)='X' 
    return Neighbors; 
    } 
+0

什麼編譯器? g ++給出警告。 – 2010-11-13 22:10:52

回答

3

如果要返回一個由四個對象組成的數組,您不一定需要使用動態分配或std::vector。你只需要將數組包裝到一個類中,以便你可以返回它。例如:

struct GetNeighborsResult 
{ 
    CoordwValue Value[4]; 
}; 

GetNeighborsResult getNeighbors(); 

升壓,TR1和C++ 0x中都可以方便地使用用於此目的的容器狀array類模板:

std::array<CoordwValue, 4> getNeighbors(); 

使用array的優點是你不必爲每個類型和數字編寫一個單獨的類,你可以使用類模板。

如果您確實選擇返回指向動態分配數組的指針,使用智能指針來管理內存。沒有理由不使用智能指針。

4

您正在返回一個指向堆棧分配數組的指針。這個數組在函數返回時將不再存在,所以指針實際上會失效,儘管它仍然可以工作(直到你調用另一個函數,例如cout,它可能會被新的堆棧段刪除)。你可能想這樣說:

CoordwValue *Neighbors = new CoordwValue[4]; 

取而代之的是:

CoordwValue Neighbors[4]; 

當然,那麼它需要調用函數(main在這種情況下)正確delete[]數組的時候它完成使用它。

+0

+1,不要忘記調用delete [] :) – 2010-11-13 21:48:15

+0

@redDragon:這被稱爲未定義的行爲,實際上意味着你的程序的行爲是不可預知的 – 2010-11-13 21:48:46

+0

@dark_charlie:只是編輯它來添加它。 :) – cdhowie 2010-11-13 21:49:08

1

返回的數組在stack上創建並返回。我建議閱讀堆和內存的差異here

如果需要從函數返回數組,您可以使用new動態分配內存。但是,內存必須與delete一起發佈,否則將導致內存泄漏。

STL容器使用動態內存並且超載了copy constructor。用vector<T>替換數組將允許您安全地返回值。

0

問題是你正在堆棧上返回一個變量。變量Neighbors在方法getNeighbors的堆棧中創建。當你離開這個方法時,內存被破壞,破壞你的返回值。

如何解決?傳入外部創建的數組並填入數值。

0

您正在返回本地變量的地址。當getNeighbors返回時,Neighbors[4]超出範圍,導致各種問題,包括應該是編譯器警告/錯誤。

你有幾個選擇:首先,做什麼cdhowie說,並返回一個動態分配的數組。另一個是按值返回,所以返回的是COPY Neighbors[4],而不是指向它的指針。我認爲這樣的語法可能類似於CoordwValue getNeighbors()[4] { .... }

還有一種方法是讓調用者傳入您填寫的預分配數組。

+0

您使用的語法是正確的,但是您要應用的語義不是:一個函數不能有返回類型的數組類型(沒有數組和沒有函數類型)。 – 2010-11-13 21:58:28