6
#include <iostream>
using namespace std;

int* flipArray(int input[], int n)
{
    int output[n];
    int pos = 0;
    for (int i = n-1; i >= 0; i--)
    {
        output[pos++] = input[i];
    }
    int* p = output;
    for (int k = 0; k < n; k++)
        cout << *p-k << endl << endl;
    return p;
}

int main()
{
    const int SIZE = 5;
    int firstArray[SIZE];
    for (int n = 0; n < SIZE; n++)
    {
        firstArray[n] = n+1;
    }
    int* a;
    a = flipArray(firstArray, SIZE);
    for (int j = 0; j < SIZE; j++)
        cout << *a-j << endl;

    cout << endl;
    cout << *a << '\t' << *a+1 << '\t' << *a+2;
    return 0;
}

I am attempting to flip firstArray using a function that returns a pointer, but I am struggling to understand how accessing an index using a pointer works.

Here is why I am confused: Within the function flipArray, the following for-loop:

for (int k = 0; k < n; k++)
    cout << *p-k << ' ';

prints "5 4 3 2 1" to the console. It was my understanding that I should be accessing an element of a vector with *(p+k), not *(p-k). If I print *(p+k), "5 6 7 8 9" is printed to the console. If I print the array without pointers and using k as the index location, "5 4 3 2 1" is printed to the console.

Within my main function, however, the values of *a which is assigned pointer p from the flipArray function, I do not get the same results:

for (int j = 0; j < SIZE; j++)
    cout << *a-j << endl;

prints 5 0 -1 -2 -3 to the console, and

    for (int j = 0; j < SIZE; j++)
    cout << *a+j << endl;

prints 5 2 3 4 5 to the console.

Further, I thought that the pointer location of *p and the pointer of location of *a should be the same! But when I print the address &p in the function, I get the location of 0x28fde0, and when I print the address of &a in the main, I get the location 0x28fedc. Of course, these were done during the same run.

Could someone tell me where I have gone astray? Thanks!


Thanks to everyone for the informative answers.

I have updated my solution, and it is now returning what I would expect it to. I have a new question about memory leaks and when pointers need to be deleted.

int* flipArray(int input[], int n)
{
    int* output = new int[n];
    int pos = 0;
    for (int i = n-1; i >= 0; i--)
        output[pos++] = input[i];
    return output;
}

int main()
{
    const int SIZE = 5;
    int firstArray[SIZE];
    for (int n = 0; n < SIZE; n++)
    {
        firstArray[n] = n+1;
    }
    int* a;
    a = flipArray(firstArray, SIZE);
    for (int j = 0; j < SIZE; j++)
        cout << a[j] << " "; // can also be written as *(a+j), which is more prone to bugs
    delete [] a;
    return 0;
}

Will the pointer output be deleted when the function flipArray returns? If not, how should I delete output while also returning it? Is deleting the pointer a in my main function the same thing as deleting output, because they point to the same location?

5
  • 2
    returning a pointer to a local array :( Commented Apr 20, 2015 at 17:32
  • I don't get the *p-k. Looks like it should be cout << *p+k << endl << endl Commented Apr 20, 2015 at 17:33
  • returning an address from the variable created in the stack which is not right Commented Apr 20, 2015 at 17:34
  • consider std::reverse Commented Apr 20, 2015 at 17:51
  • 1
    In your new code, delete a; should be delete [] a; Commented Apr 20, 2015 at 17:52

3 Answers 3

4

It has been pointed out that your main problem is coming from the operator precedence. The * operator in *p - k is evaluated before the -. This means that k will be subtracted from the value of the int pointed at by p.

This is a huge pain, which is why the braces pointer[k] are commonly used. There are situations where using pointer arithmetic *(pointer + k) makes more sense, but it can be a source of bugs.

One point to note here: it is always better to use parenthesis even if you are not sure whether or not you need them.


You do have a second problem:

Here you are declaring output on the stack as a local variable, then you are returning output. When you return back to the previous stack frame, this pointer will be pointing to a decallocated buffer:

int* flipArray(int input[], int n)
{
    int output[n]; // allocated on the stack
    int pos = 0;
    for (int i = n-1; i >= 0; i--)
    {
        output[pos++] = input[i];
    }
    int* p = output;
    for (int k = 0; k < n; k++)
        cout << *p-k << endl << endl;
    return p; // this stack frame ends.
}

This means the contents of the buffer can be overwritten if the space the buffer is using is reallocated. Use new to allocate on the heap:

int* output = new int[n];

make sure to call delete on the pointer when you are done using it.

This bug can even present security vulnerabilities in your applications, so make sure you know when to allocate on the heap in C++.


Update:

Question: When this function returns, the array still exists in memory, and it's location is stored in the pointer a. Does returning the value output delete it? If not, will deleting the pointer a when I am done with it in the main function serve the same purpose?

When you delete the pointer, the memory pointed to that pointer is deallocated and the pointer is left dangling. A reference to a deleted pointer is pointing at memory that is technically free, which is bad. If the allocator library decides that it wants to reuse that space, your buffer, which is now in free space, will be reallocated. This means your buffer will lose all data integrity and the data inside of it cannot be trusted.

A common practice is to assign pointers to NULL when you are done using them. This way your program will crash and you will know where your bug is:

int* p = new int[10];
...
delete p;
p = NULL;
...
p[0] = 0; // this will now crash because you are accessing NULL.
Sign up to request clarification or add additional context in comments.

2 Comments

Thank you for this answer, I think that the concepts are becoming more clear. Now I am dynamically allocating the array output using the new keyword as per your suggestion. When this function returns, the array still exists in memory, and it's location is stored in the pointer a. Does returning the value output delete it? If not, will deleting the pointer a when I am done with it in the main function serve the same purpose? Thank you for your informative answer.
@greedIsGoodAha if you have a new question that is separate from this one, you should post a new question. If it is related to this question, edit your existing question and we will answer your new question.
3
for (int k = 0; k < n; k++)
    cout << *p-k ;

It was my understanding that I should be accessing an element of a vector with *(p+k), not *(p-k).

Your understanding is right.You are not accessing the array here.p points to the first element 5 and every time k is substracted from it, which gives you 5-0 5-1 5-2 and so on which is equivalent to the filpped array.So if you want to access the array using the pointer

for (int k = 0; k < n; k++)
    cout << *(p+k) ;// Note the paranthesis

Comments

2
for (int k = 0; k < n; k++)
    cout << *p-k << endl << endl;

What this code is doing is completely different from what you think it does.

*p - k will be processed like

*p = 5 - 0 = 5
*p = 5 - 1 = 4

and so on not *(p+k) or *(p-k)

For your understanding :

int a[5] = { 1,2,6,4,5};

In order to access 3rd element in the array you do

a[2] = *(a+2)

and not

*a + 2

*(a + 2) = 6 and *a + 2 = 1 + 2 = 3

Take care of not returning the pointer to the local variable which will lead to undefined behavior

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.