2

When I do this pointer arithmetic , it always give me an error


int main()
{
    const int rowSize=40;
    int* unique=nullptr;

    int arr[rowSize]={1,1,11,31,21,22,2,2,3,32,31,3,4,34,45,5,55,5,55,5,6,46,64,6,7,27,74,7,7,7,7,11,11,11,11,11,1,2,13,4};
    int amount=0;

    for (int count=0; count<rowSize; count++)
    {
        if (arr[count]!=arr[count+1])
        {
            amount++;
        }
    }
    unique= new int[amount];
    for (int count=0; count<rowSize-1; count++)
    {
        if (arr[count]!=arr[count+1])
        {
            *unique=arr[count];
            unique++;
        }
    }

    for (int count=0; count<20; count++)
    {
        cout<<unique[count]<<" ";
    }
    cout<<endl;
    delete [] unique;
    unique=nullptr;
    return 0;
}

Everytime I do this pointer arithmetic, *unique=arr[count] and unique++, it always give me a funky output at the end.

6
  • Does this code compile? What is the value of RowSize? Commented May 5, 2020 at 13:58
  • int the line if( arr[count] != arr[count+1]) when count is on the last element (rowSize -1) you access arr[count+1] where count+1 == rowSize this is out of range of your array. The last element is then just some garbage value ;) just make your loop for (int count=0; count < rowSize - 1; count++) and everthing will work. Commented May 5, 2020 at 13:59
  • @cigien MB, rowSize=40 I forgot to put it during copying this code. it is just a piece of function, it compile thou but it just give a funny output. Commented May 5, 2020 at 14:08
  • You might think that the information you leave out is not relevant. But we cant know that, so you should always provide a minimal-reproducible-example Commented May 5, 2020 at 14:10
  • @cigien, well there I edit it so it should be compilable. Commented May 5, 2020 at 14:27

1 Answer 1

1

Changing the value of a pointer returned by the new[] operator is extremely dangerous, and never really the right way to go about coding. This is because, at some point, you will need to release that memory with a delete[] 'call' to the address that new[] gave you.

In your case, the module that calls your uniqueArr function gets a returned value that will no longer (in most cases) be the correct address for the delete[] call, and that will fail.

You would be far better off using the [] operator on your pointer, using an index value that you increment when appropriate (where you currently increment the pointer). Something like this:

//...
    int* unique = new int[amount];
    size_t uIndex = 0;

    for (int count=0; count<rowSize-1; count++)
    {
        if (arr[count]!=arr[count+1])
        {
            unique[uIndex] = arr[count]; // The [] works fine with a 'new[]' pointer!
            uIndex++; // You could even include this POST-increment inside the [], above!
        }
    }
//... You can now 're-use' "unique" as it will still be the original address.
//...

In this way, the value returned by the function will be unchanged from that returned by the new[] operator, and will be valid for any subsequent delete[] operation.

Feel free to ask for further clarification an/or explanation.

EDIT: An alternative (though, IMHO not good) approach would be to have a second int* pointer in which you save the value of unique, then restore unique to that value before 're-using' it (in a second loop, or before calling delete[]).

Sign up to request clarification or add additional context in comments.

1 Comment

Well, thanks for the help it give me the right output.

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.