-1

I'm very new to C++ but have been programming in less hard core languages (java, python) for a couple of years. I just encountered a very weird error in my code and am looking for an explaination and a solution.

I have created an array of doubles in a function, returned a pointer and am now trying to access the elemts of the array. I can access any element just fine as you would, arr[i], but as I try to access a second element (yes "a" second, not "the" second) everything goes very wrong. Sometimes I get zero and the rest of the time I get very big numbers (close to the the biggest double which isn't infinity, 1.7...10^308).´

As I understand accessing a position in the array which isn't actually in the array should render these kind of results but even running cout<<arr[1]<<", "<<arr[0]; prints first what's expected and then something very unreasonable.

I am really trying to properly understand what's going on so any help is appreciated but remember I am very new to C++, thanks.

-----EDIT-----

Here's what gives me the problem:

double* fun(){
    double arr[] = {3.14, 2.7, 1.0};
    return arr;
}

int main(){
    double* arr = fun();
    cout<<arr[1]<<", "<<arr[0]<<endl;

    return 0;
}

/* Prints "2.7, 0" */
Ivar Eriksson
  • 863
  • 1
  • 15
  • 30

3 Answers3

1

You are not allowed to return a pointer to the stack-allocated variable (or to the array) because it leads to the undefined behaviour. You should allocate your array at the heap via new:

double *fun(){
    double *arr = new double[3];
    arr[0] = 1;
    arr[1] = - 123.45;
    arr[2] = 42;

    return arr;
}

Or you can use a standard container for a static array, which is even better and much more convenient:

#include <array>

std::array<double, 3> fun(){
    std::array<double, 3> result = {3.14, 2.7, 1.0};
    return result;
}
LibertyPaul
  • 1,139
  • 8
  • 26
  • Well yeah, you _can_ do that, if you want it to compile without warnings and run without segfaulting. But there's no way the `std::` way is better or more convenient. – ocket8888 Apr 26 '16 at 21:00
  • @ocket8888 In terms of language everything what leads to the undefined behaviour is prohibited. But compilers don't care, so.. – LibertyPaul Apr 26 '16 at 21:02
  • Thanks, this finally fixed it but I understand that I should `free(arr)` if I use the conventional C++ arrays. Am I right and in this case what does that really do? – Ivar Eriksson Apr 26 '16 at 21:08
  • no, use `delete` in C++. What I posted was wrong because of that, and I changed it before you commented, but apparently not until after you tried it. That will de-allocate the memory, otherwise other programs won't be able to use that memory, even after you're done with it. – ocket8888 Apr 26 '16 at 21:12
  • @IvarEriksson It's bad to create an object in one place and destroy it in another, but yes, you should free this memory via `delete[] arr;`. – LibertyPaul Apr 26 '16 at 21:14
  • Another possibility is to declare the variable as `static` within the function. The `static` keyword makes the variable hang around until the program terminates. – Thomas Matthews Apr 26 '16 at 22:16
  • @ThomasMatthews Worst antipattern I've ever seen :D – LibertyPaul Apr 26 '16 at 22:17
  • @LibertyPaul What? Thomas Matthews solution works perfectly, and provided the memory is freed as soon as it's not needed it's not wasting anything. Plus, not `delete`ing the array as soon as you don't need it, even if that's outside the function, is totally bad practice. – ocket8888 Apr 27 '16 at 16:29
  • @ocket8888 Yes, it woks like a vast of shitty examples (Welcome to C/C++ :-)) But anyway you shouldn't do that. – LibertyPaul Apr 27 '16 at 16:58
  • Why not? That's what `static` is for, outside of class definitions. – ocket8888 Apr 27 '16 at 17:02
0

In C++, you can technically access elements in an array that are un-allocated. Other languages, such as Java actually prevent you from doing this. If it is giving you back junk values, you are accessing un-allocated space. Make sure you check your bounds. For example:

double array[10];
cout << array[100]; // gives back junk value because it was not allocated. You need to stay within the index values 0 - 9.

works... but

double array[10];
cin >> array[100];  // Cause an error. Seg fault most likely

will give you back an error.

Retro Gamer
  • 1,096
  • 1
  • 10
  • 24
-2

The problem is that the array is created on the stack and that a pointer to this object is returned. Basically you are returning a dangling pointer.

To solve this you need to allocate memory for the array:

double* fun() {
    auto arr = new double[3]{ 3.14, 2.7, 1.0 };
    return arr;
}

Keep in mind that you need to free the memory. A better approach would be to use std::vector or std::array for fixed-size array. The heap memory for those objects will safely be managed by the object's lifetime (RAII).

std::array<double,3> fun() {
    return { 3.14, 2.7, 1.0 };
}

or using vector:

std::vector<double> fun() {
    return { 3.14, 2.7, 1.0 };
}
A.Fagrell
  • 1,052
  • 8
  • 21