2011-08-10 209 views
0

我期待下面的代碼打印1,但它的打印數量是隨機的。 我不明白爲什麼會發生這種情況,請指教。C++傳遞指針

#include <iostream> 
using namespace std; 

int * returnArray() 
{ 
    int myArray[5]={1,2,3,4,5}; 
    return myArray; 
} 

void printArray(int * myArray) 
{ 
    cout << *myArray<< endl; 
} 

int main() 
{ 
    printArray(returnArray()); 
} 
+1

'returnArray'中的數組正在堆棧中分配,與其他本地變量相同。當'returnArray'返回時,用於存放數組的內存從堆棧彈出,並可以自由用於其他目的。如果你想要一個數組持續超出聲明的範圍,你必須使用'new'來分配它。 – luqui

+3

http://stackoverflow.com/questions/6441218/can-a-local-variables-memory-be-accessed-outside-its-scope/6445794#6445794 < - 所以,你租一個酒店房間 –

+0

@luqui你也可以malloc –

回答

5

在您的代碼中,returnArray返回指向函數本地的第一個元素myArray的指針。當函數返回時,它的局部變量的內存會在調用堆棧彈出時被釋放,所以它可以用於其他目的。在這種情況下,由於您之後調用了printArray,原來由returnArray佔用的堆棧區域被重新用於printArray,所以原來包含myArray的內存現在具有不可預知的內容。

正如詹姆斯甘孜指出,最好的方式來完成你想要很可能會使用std::vector<int>代替int*,像這樣

std::vector<int> returnArray() 
{ 
    int myArray[5] = { 1, 2, 3, 4, 5 }; 
    std::vector<int> result(myArray, myArray + 5); 
    return result 
} 

,並相應修改等功能採取了矢量什麼。請注意,在printArray中,您需要myVector[0]來訪問第一個元素,因爲向量不是指針。

+1

最簡潔的解決方案是返回一個'std :: vector '。這樣,來電者就可以得到他想要的,而不必擔心釋放任何東西。 –

+1

@jk:答案是正確的,但建議的解決方案是不正確的,實際上是一種邪惡。爲什麼使用數組?C++已經提供了'std :: vector',建議的解決方案應該使用'std :: vector'而不是動態分配的數組。 –

+0

或者您可以使用靜態持續時間對象。 –

2

功能returnArray被有效地返回一個指針堆棧數據,這將不再有效,它返回之後。變量myArray[5]存儲在堆棧中。函數返回後,堆棧用於存儲其他數據。所以返回地址的值對調用函數沒有意義。

2

因爲此代碼導致未定義的行爲
你的數組對於函數是本地的,當函數返回時它會被銷燬。
在函數中返回指向局部變量的指針或引用是未定義行爲。

未定義的行爲意味着任何事情都可能發生,行爲無法解釋。程序可能工作,也可能不工作甚至崩潰,定義結果是不可能的。

0

當您在printArray函數中引用它時,int myArray []超出範圍。這意味着printArray()中的指針* myArray指向堆棧上的一些不再有效的垃圾。

0

當returnArray返回時,myArray超出範圍。換句話說,您正在返回一個指向不再存在的數據的指針。

有幾個解決方案。你可以把myArray的一個全局變量,或者你可以動態地分配它,因爲在

int myArray[5] = new int[5]; 

如果你這樣做,你就必須刪除它時,你不再需要它,使用如下語句

delete[] myArray; 
0

將您的數組對象更改爲永久。
即。使其成爲靜態存儲持續時間對象。這意味着它的壽命將持續比函數調用更長的時間/

int * returnArray() 
{ 
    static int myArray[5]={1,2,3,4,5}; 
    //^^^^^^ 
    // a static in function scope means the variable is a static storage duration 
    // object. This means its life span is longer than the application (ie it will 
    // be tidied up after main exits). 
    // 
    // Thus it is perfectly valid to return it as the result from the function. 

    return myArray; 
} 

在您的版本中,該對象是一個自動變量。
這意味着它在超出範圍之後不再存在(在函數結束時)。