3

I got a problem with the following code:

#include <iostream>
using namespace std;

double* FillArray(void) 
{   
    double result[5]; 

    for (int i = 0; i<5;i++){
        result[i]=(double) i;

    }
    return result; // return the pointer
}

int main()
{   

    double * a = FillArray();
    for (int i = 0; i<5;i++){
        cout << a[i] << endl; // print out the array
    }

    return 0;
}

The outputs are strange:

0
3.47187e-236
8.89753e-308
8.8976e-308
3.90251e-236

Could you tell what wrong in my code? I tried to use a function to return an array, and print out it in the main().

lxw
  • 91
  • 1
  • 6
  • The result array goes out of scope at the end of the FillArray() function. – mocj Jul 24 '13 at 19:28
  • Turn up the warning level on your compiler, it should have told you something was fishy about this code. – Mark Ransom Jul 24 '13 at 19:29
  • There's a huge problem with your title: "c/c++". Stick to one of both languages. Either leave C++ behind, or delve into the realm of `std::vector` and his useful companions. – Zeta Jul 24 '13 at 19:32
  • possible duplicate of [Can a local variable's memory be accessed outside its scope?](http://stackoverflow.com/questions/6441218/can-a-local-variables-memory-be-accessed-outside-its-scope) – chris Jul 24 '13 at 19:45

4 Answers4

4

You are returning a pointer to a local variable, the array result. This is undefined behaviour. The variable ceases to exist when the function returns, so by the time you get to printing, you print garbage values.

If you really want to return an array, you can use an std::array:

typedef std::array<double, 5> DArray5;

DArray5 FillArray() 
{
    DArray5 result; 

    for (size_t i = 0; i < result.size(); ++i){
        result[i] = i;
    }
    return result;
}

Edit This is a C++ only answer. There is no C/C++ language.

juanchopanza
  • 223,364
  • 34
  • 402
  • 480
  • For OP: if you don't know what undefined behaviour is, have a look at http://stackoverflow.com/questions/2397984/undefined-unspecified-and-implementation-defined-behavior/4105123#4105123. – Zeta Jul 24 '13 at 19:34
  • So, what is the reason for the down-vote? Is there anything wrong, misleading or controversial in this answer? If so, I would gladly think about making changes. – juanchopanza Jul 24 '13 at 21:04
  • A couple of issues: 1) an array (or, arguably better, vector) exists only in C++ - not C. 2) I would discourage hard-coding "5" multiple times. 3) In the same vein, I would use container::begin() .. container::end() instead of (for (int i=0; i < 5; i++). IMHO... – paulsm4 Jul 24 '13 at 21:06
  • 1
    @paulsm4 fair enough, except that I wouldn't use the iterators because the index is needed. And I don't want to confuse OP with `std::iota` just yet, and I don't agree that `vector` is a better solution. OP has a fixed size array. As for C, I find that irrelevant here, since the question is tagged C++. – juanchopanza Jul 24 '13 at 21:12
  • Thank you, but "std::array" can only be use in visual studio 2012. – lxw Jul 25 '13 at 15:35
  • @PengLi In general, you should specify special restrictions that prevent you from using the current C++ standard. But there are alternatives. There is `std::tr1::array` and `boost::array`. Then there are a whole bunch of standard library containers, such as `std::vector`. – juanchopanza Jul 26 '13 at 06:10
2

result is allocated in the stack. Try allocating it in the heap, like this:

double* result = new double[5]; 
wjmolina
  • 2,625
  • 2
  • 26
  • 35
  • Thank you, but I have to delete it after use. – lxw Jul 25 '13 at 15:32
  • You're welcome. In `main` you write `double* a = FillArray();`. So, I thought you wanted to use dynamically allocated data to begin with; I didn't want to change `FillArray`'s signature. – wjmolina Jul 25 '13 at 16:02
0

The array called result get released. Try this code:

#include <iostream>
using namespace std;

void FillArray(double *result) 
{   
    for (int i = 0; i<5;i++){
        result[i]=(double) i;
    }
}

int main()
{   
    double result[5]; 
    FillArray(result);
    for (int i = 0; i<5;i++){
        cout << result[i] << endl; // print out the array
    }

    return 0;
}
zs2020
  • 53,766
  • 29
  • 154
  • 219
-1

This is WRONG:

double* FillArray(void) 
{   
    // Result ONLY has scope INSIDE of the FillArray function
    double result[5]; 

    for (int i = 0; i<5;i++){
        result[i]=(double) i;

    }
    // Bad things will happen when the caller tries to use (now-invalid) "result"
    return result;

Here is one correct alternative:

#define ARRAY_SIZE 5

main ()
    double result[ARRAY_SIZE]; 
    FillArray (result, ARRAY_SIZE);
    for (int i = 0; i<ARRAY_SIZE;i++){
        cout << result[i] << endl; // print out the array
    }
    ...
void FillArray(double *array, int n) 
{   
    for (int i = 0; i<n;i++){
        array[i]=(double) i;
paulsm4
  • 114,292
  • 17
  • 138
  • 190