2011-08-10 175 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; 
} 

在您的版本中,该对象是一个自动变量。
这意味着它在超出范围之后不再存在(在函数结束时)。