-5

I'm trying to understand C pointers, I set up the following example:

int main()
{
    int temp[] = {45,67,99};    
    int* address;
    address = &temp[0]; //equivalent to address = temp;
    std::cout << "element 0: " << *address << std::endl;
    address = (address + sizeof(int));
    std::cout << "element 1: " << *address << std::endl;

    std::getchar();
    return 0;
}

Now, the first element is printed correctly while the second one is garbage. I know that I can just use:

address = (address + 1);

in order to move the pointer to the second element of the array, but I don't understand why the first method is wrong.

Baum mit Augen
  • 49,044
  • 25
  • 144
  • 182
rekotc
  • 595
  • 1
  • 10
  • 21
  • 5
    If you know that `address = (address + 1);` is right, then why do you expect `address = (address + sizeof(int));` to be right, too? Of course you get a different result when you add a different number. – Baum mit Augen Aug 02 '17 at 21:25
  • 1
    The previous 6 questions on c++ have been downvoted to oblivion. Someone is going on a downvoting spree. – Devin L. Aug 02 '17 at 21:25
  • If you wanted to actually advance `sizeof(int)` *bytes*, that pointer should have been casted to `char *` and then advanced by `sizeof(int)`. – PaulMcKenzie Aug 02 '17 at 21:29
  • @BaummitAugen because i couldnt' see the difference between the two – rekotc Aug 02 '17 at 21:35
  • @DevinLiu multiple downvotes require multiple people willing to sacrifice rep to express their displeasure with the question. Usually this is a sign of a weak question. Runs of multiple downvotes suggests nothing more than a run of weak questions. – user4581301 Aug 02 '17 at 21:36
  • 1
    Just printing out `sizeof(int)` might have helped then. Btw, no need to approve every edit proposed on your posts, that last one made it way worse. – Baum mit Augen Aug 02 '17 at 21:37
  • @baummitAugen ok, i will remember your suggestions, thanks. – rekotc Aug 02 '17 at 21:37
  • @user4581301 You don’t lose rep for downvoting questions, only answers. And at least in its current state, this question doesn’t seem to deserve nearly as low a score as it has. – Daniel H Aug 02 '17 at 23:12
  • @DanielH Did not know that. I'll have to start downvoting more questions. Muhuhahahahahaha! The monster is unleashed! But seriously folks, I think I'll stick to my current downvoting strategy. – user4581301 Aug 02 '17 at 23:29

3 Answers3

6

The operator sizeof returns the size of the object in bytes. So (depending on your compiler) you may have just done

address + sizeof(int) == address + 4

This will obviously access out of bounds when you dereference the pointer. The problem is that the way you are trying to use sizeof is already accounted for in the pointer arithmetic. When you add an integral (e.g. 1) to an int* it already knows to move 1 int over to the next address.

Cory Kramer
  • 114,268
  • 16
  • 167
  • 218
4

Incrementing a pointer by N will not increment it by N bytes, but by N * sizeof(pointed_type) bytes.

So when you do:

address = (address + sizeof(int));

You are incrementing the address by (probably) 4 times the size of int, which is past your original array.

What you intended to do is:

address = reinterpret_cast<int*>(reinterpret_cast<char*>(address) + sizeof(int));

Which is pretty horrendous.

  • 1
    @Ron When you cast to `char*` advancing the pointer moves 1 byte at a time. Then after moving the correct number of bytes, you cast back to `int*` so the new address is interpreted correctly during the dereference operation. – Cory Kramer Aug 02 '17 at 21:31
  • @Ron I interpreted the asker's question as "I wanted to increment the pointer by a number of bytes, why can't I do that?" I showed him how to accomplish his intent. –  Aug 02 '17 at 21:31
1

An array is a group of elements of the Same Type mapped consecutively in memory one-next to the other.

The size of the array is:

sizeof(any element) * the number of elements

So the vice-vers to get the number of elements of an array you can:

Number of elements = sizeof(array) / sizeof(any element).
  • These elements are addressable and each one is addressed with the first byte's address.

    int a[] = {1, 10, 100, 1000, 10000};
    std::cout << sizeof(int) << std::endl; // 4
    std::cout << sizeof(a) << std::endl; // 20: 5 * 4
    
  • The addresses:

    cout << &a[0] << " : " << &a[1] << " : " <<
        &a[2] << " : " << &a[3] << endl;
    
  • The outPut:

    0018FF38 : 0018FF3C : 0018FF40 : 0018FF44
    

As you can see the address is incrementing by sizeof(int) // 4

  • To do it on your way:

    for(int* tmp = array; tmp <= a + nElement; tmp++)
        cout << tmp << " : ";
    

The result:

    0018FF38 : 0018FF3C : 0018FF40 : 0018FF44

As you can see the result is identical.

  • To move from one element to another just increment / decrement the address as I did above:

    tmp++; // incrementing the address by 1 means moving to the next element, element means an integer which means 4 bytes. 1 here is not a single byte but a unit or element which is 4 byte here;
    
  • To move to the n-element just:

    tmp += n;
    

In your example:

    address = (address + sizeof(int)); : 
    address = address + 4; // moving  to the 0 + 4 element which means fifth element (here outbound).
Raindrop7
  • 3,889
  • 3
  • 16
  • 27