MichaelTaylor3D
MichaelTaylor3D

Reputation: 1665

accessing array elements from pointer in C++

Im new to c++, and Ive read a lot of posts on stack overflow about this issue. Please tell me what Im not understanding, it seems basic....so why?

int* getArray() {
    int a[] = { 3, 4, 3, 1, 5 };    
    return a;
}

void main() {
    int *result = getArray();
    for(int i = 0; i < 5; i++) {
        std::cout << result[i] << std::endl;
    }
}

returns:

3

263996040

-1

4651964

263540469

Upvotes: 0

Views: 60

Answers (3)

Ashok
Ashok

Reputation: 6244

Don't use "local" variable (stack allocated memory) and return it back. Instead use dynamic (heap allocated memory) variable and return it back and ask the caller to destroy it after use.

Like this...

void getArray(int** a, int &size)
{
    size = 5;
    // Allocate memory on heap so it remain accessible until destroyed explicitly.
    int *arr = new int[size];
    for (int i = 0; i<size; ++i)
    {
        arr[i] = i;
    }

    *a = arr;
    return;
}

int main() {
    int *a = NULL;
    int arrSize = 0;

    getArray(&a, arrSize);
    for(int i = 0; i < arrSize; i++) {
        std::cout << a[i] << std::endl;
    }

    // Release/Destroy the memory. DON'T FORGET TO CALL THIS ONCE YOU ARE DONE with 'a' !!
    delete a;

}

Upvotes: 1

Floris
Floris

Reputation: 46365

Nice one. The array you created in your function stops existing when the function returns.

You can make it "persist" by adding the static keyword:

int* getArray() {
    static int a[] = { 3, 4, 3, 1, 5 };    
    return a;
}

void main() {
    int *result = getArray();
    for(int i = 0; i < 5; i++) {
        std::cout << result[i] << std::endl;
    }
}

static makes the array remain in memory after the function returns - usually because you want to use it again in the function. It is considered "ugly" to do the above, but it works...

What you are seeing is the fact that the memory, once freed after the return from getArray(), is happily being re-used for other purposes. In fact there is no telling what ends up in there (possibly some temporary storage for the cout function), and when you interpret it as an int (because you are accessing these memory locations with the int *a pointer), you will just see the int representation of whatever bytes happen to be there.

update the "not quite so ugly way" to do this:

int getArray(int *a, int n) {
    int ii, lim;
    int temp[]= { 3, 4, 3, 1, 5 };          // temp exists in scope of function, will disappear after
    lim = (sizeof(temp),n)?sizeof(temp):n;  // copy no more than exist in temp, 
                                            // or than there is space in a
    for(ii = 0; ii < lim; ii++) {
      a[ii] = temp[ii];               // copy temp to "permanent" location
    }
    return lim;                         // this now returns the size of the array
}

void main() {
  int a[10];     // deliberately allocating too much space...
  int b;
  b = getArray(a);  // function returns actual number of elements allocated    
    for(int i = 0; i < b; i++) {
        std::cout << result[i] << std::endl;
    }
}

Upvotes: 1

shaoyl85
shaoyl85

Reputation: 1964

a is a temporary variable which will be deconstructed after the function getArray finishes execution. So "result" points to some memory that is invalid.

Upvotes: 1

Related Questions