How do I return an array from a function?

2020-05-06 10:51发布

I don't get a error message when I compile the code but I cant a proper result.

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

This part of the code prints X01X

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

But I can't get the same result from

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

What is the problem?

Edit:

This version of the code works fine.

#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条回答
Bombasti
2楼-- · 2020-05-06 11:19

You are returning a pointer to a stack-allocated array. This array will cease to exist when the function returns, so the pointer will effectively be invalid though it may still work (until you call another function, such as cout, when it will probably be wiped out by the new stack segment). You probably want to say this:

CoordwValue *Neighbors = new CoordwValue[4];

Instead of this:

CoordwValue Neighbors[4];

Of course, then it's up to the calling function (main in this case) to properly delete[] the array when it is finished using it.

查看更多
爷、活的狠高调
3楼-- · 2020-05-06 11:26

The problem is that you are returning a variable on the stack. The variable Neighbors is created in on the stack in the method getNeighbors. When you leave this method, the memory is destroyed, corrupting your return value.

How to fix it? Pass in an array created on the outside and fill the values in.

查看更多
时光不老,我们不散
4楼-- · 2020-05-06 11:31

Returned array is created on the stack and returned. I'd suggest to read about difference of heap and stack memory here.

If array needs to be returned from a function you have an option of allocating memory dynamically using new. However, then the memory must be released with delete or it will result in a memory leak.

STL containers use dynamic memory and have overloaded copy constructor. Replacing array with vector<T> will allow you to return the values safely.

查看更多
Emotional °昔
5楼-- · 2020-05-06 11:32

You are returning the address of a local variable. When getNeighbors returns, Neighbors[4] goes out of scope, causing all sorts of problems, including what should be a compiler warning/error.

You have a couple of options around this: first, do what cdhowie said and return a dynamically allocated array. Another is to return by value, so the return is a COPY of Neighbors[4], not a pointer to it. I think the syntax for this would be something like CoordwValue getNeighbors()[4] { .... }

Yet another is to have the caller pass in a pre-allocated array that you fill in.

查看更多
Juvenile、少年°
6楼-- · 2020-05-06 11:39

If you want to return an array of four objects, you don't necessarily need to use dynamic allocation or std::vector. You just need to wrap the array in a class so that you can return it. For example:

struct GetNeighborsResult
{
    CoordwValue Value[4];
};

GetNeighborsResult getNeighbors();

Boost, TR1, and C++0x all have a container-like array class template that you can easily use for this purpose:

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

The advantage of using array is that you don't have to write a separate class for every type and number that you have, you can just use the class template.

If you do choose to return a pointer to a dynamically allocated array, use a smart pointer to manage the memory. There is no reason whatsoever to not use a smart pointer.

查看更多
登录 后发表回答