如何从函数返回数组?

时间:2010-11-13 21:44:51

标签: c++ arrays struct

编译代码时,我没有收到错误消息但是我没有正确的结果。

#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;
    }

5 个答案:

答案 0 :(得分:4)

您正在返回指向堆栈分配数组的指针。当函数返回时,这个数组将不复存在,所以指针实际上是无效的,虽然它可能仍然有效(直到你调用另一个函数,如cout,它可能会被新的堆栈段消灭)。你可能想这样说:

CoordwValue *Neighbors = new CoordwValue[4];

而不是:

CoordwValue Neighbors[4];

当然,接下来是调用函数(在这种情况下为main)在数组完成使用后正确地delete[]

答案 1 :(得分:3)

如果要返回包含四个对象的数组,则不一定需要使用动态分配或std::vector。您只需将数组包装在一个类中,以便可以返回它。例如:

struct GetNeighborsResult
{
    CoordwValue Value[4];
};

GetNeighborsResult getNeighbors();

Boost,TR1和C ++ 0x都有一个类似于容器的array类模板,您可以轻松地将其用于此目的:

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

使用array的优点是您不必为每个类型和数字编写单独的类,您只需使用类模板。

如果确实选择返回指向动态分配数组的指针,使用智能指针来管理内存。没有任何理由不使用智能指针。

答案 2 :(得分:1)

返回的数组在stack上创建并返回。我建议阅读有关堆和堆栈内存的差异here

如果需要从函数返回数组,则可以选择使用new动态分配内存。但是,必须使用delete释放内存,否则会导致内存泄漏。

STL容器使用动态内存并且重载copy constructor。用vector<T>替换数组将允许您安全地返回值。

答案 3 :(得分:0)

问题是你在堆栈上返回一个变量。变量Neighbors在方法getNeighbors中的堆栈中创建。当您离开此方法时,内存将被破坏,从而破坏您的返回值。

如何解决?传入在外部创建的数组并填充。

中的值

答案 4 :(得分:0)

您正在返回本地变量的地址。当getNeighbors返回时,Neighbors[4]超出范围,导致各种问题,包括应该是编译器警告/错误。

你有几个选择:首先,做cdhowie说的并返回一个动态分配的数组。另一种是按值返回,因此返回值是Neighbors[4]的COPY,而不是指向它的指针。我认为这个的语法类似于CoordwValue getNeighbors()[4] { .... }

另一种方法是让调用者传入您填写的预分配数组。