0

I have following code that returns integer array from a function.

1.  #include <iostream>
2.  using namespace std;
3. 
4.  int* AddData() {
5.  int factors[10];
6. 
7.  for (int start = 0; start < 10; start++) {
8.      factors[start] = start + 1;
9.  }
10. return factors;
11. }
12. 
13. void main() {
14. int* factors = AddData();
15. for (int i = 0; i < 10; i++) {
16.     cout << factors[i] << "\n";
17. }
18. }

Please find below screenshot which shows that line 10 has all values occupied with int values.

enter image description here

But, when it comes back to the calling function, it shows output below.

enter image description here

Am I missing anything?

Pankaj
  • 9,749
  • 32
  • 139
  • 283
  • 1
    You can't return automatic variables back by pointer/reference. I recommend you read about stack/heap allocated memory. – Mansoor Nov 02 '20 at 17:13
  • 3
    Didn't the compiler [warn you](http://coliru.stacked-crooked.com/a/86a58c7f10ac74a5) of this issue? – PaulMcKenzie Nov 02 '20 at 17:15
  • You have marked this as C++, so you should know that if you defined a `std:array` rather than a C style array, then you would be able to return by value. – Mansoor Nov 02 '20 at 17:16
  • Returning pointers to objects which have already been destroyed is a classic error in C and C++. Neither language gives you any protection against this kind of error. It one reason why (in C++ at least) you should generally avoid pointers. C++ has good alternatives for most situations in which you might want to use a pionter. – john Nov 02 '20 at 17:18

2 Answers2

3
int factors[10];
// ...
return factors;

This will lead to undefined behavior. You return a pointer to the factors array, and then, since the function ends, the factors array is immediately destroyed.

So if you try to use the pointer returned, you'll be accessing memory you have no control over. Hence undefined behavior.

Instead, either allocate the memory for the array dynamically so it won't be destroyed at the end of the function. Or even better, use an std::array!

std::array<int, 10> factors;
// ...
return factors;
scohe001
  • 15,110
  • 2
  • 31
  • 51
2

An array decays into a pointer to its 1st element. You are returning a pointer to an element of a local array that gets destroyed when it goes out of scope at function exit, thus the caller ends up with a dangling pointer to invalid memory.

To solve this, you have several options:

You can let the caller allocate the array first, and then pass it by pointer/reference into the function to fill it in:

#include <iostream>
using namespace std;

void AddData(int (&factors)[10]) {
// or: void AddData(int *factors) {
    for (int start = 0; start < 10; start++) {
        factors[start] = start + 1;
    }
}

void main() {
    int factors[10];
    AddData(factors);
    for (int i = 0; i < 10; i++) {
        cout << factors[i] << "\n";
    }
}

Or, you can let the function allocate the array dynamically so it is not destroyed until the caller is done using it:

#include <iostream>
using namespace std;

int* AddData() {
    int *factors = new int[10];
    for (int start = 0; start < 10; start++) {
        factors[start] = start + 1;
    }
    return factors;
}

void main() {
    int *factors = AddData();
    for (int i = 0; i < 10; i++) {
        cout << factors[i] << "\n";
    }
    delete[] factors;
}

In which case, you should return the array as a std::vector instead, and let it manage the dynamic memory for you:

#include <iostream>
#include <vector>
using namespace std;

vector<int> AddData() {
    vector<int> factors(10);
    for (int start = 0; start < 10; start++) {
        factors[start] = start + 1;
    }
    return factors;
}

void main() {
    vector<int> factors = AddData();
    for (int i = 0; i < 10; i++) {
        cout << factors[i] << "\n";
    }
}

Or, since the number of array elements is fixed at compile-time in your example, you can use std::array instead:

#include <iostream>
#include <array>
using namespace std;

array<int,10> AddData() {
    array<int,10> factors;
    for (int start = 0; start < 10; start++) {
        factors[start] = start + 1;
    }
    return factors;
}

void main() {
    array<int,10> factors = AddData();
    for (int i = 0; i < 10; i++) {
        cout << factors[i] << "\n";
    }
}
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770