1

I don't understand how pointers works exactly in arrays.

#include <stdio.h>
int main() {

  int x[5] = {1, 2, 3, 4, 5};
  int* ptr;

  // ptr is assigned the address of the third element
  ptr = &x[2]; 

  printf("value ptr = %d \n", *ptr);   // 3
  printf("address ptr = %d \n", ptr);   // 3
  printf("value ptr+2 = %d \n", *(ptr+2)); // 4
  printf("address ptr+2 = %d \n", (ptr+2)); // 4

  return 0;
}

The result:

value ptr = 3
address ptr = -1931225192
value ptr+2 = 5
address ptr+2 = -1931225184

The difference between ptr and ptr + 2 are 8 bytes. So when ptr is equal to -1931225192 then why isn't ptr + 2 equal to -1931225192 + 2 but instead it is -1931225192 - 8?

Can someone explain how this works? Because it is logical to add 2 to the original value which was -1931225192 but instead this +2 changes into -8.

2
  • 1
    why ptr + 2 isn't equal to -1931225192 + 2 but instead it is -1931225192 - 8 Its not +2 but +8 (not -8) exactly because The difference between ptr and ptr + 2 are 8 bytes.. Commented Oct 14, 2023 at 22:20
  • 2
    You should be using %p to print pointers, not %d. Commented Oct 14, 2023 at 22:28

2 Answers 2

1
  1. When you add an integer to a pointer, you are not adding a fixed number of bytes. You are adding a fixed number of elements. This means you are implicitly adding n*sizeof(int) bytes. To avoid this, you can cast your array to a char * if you want to strictly add a number of bytes.

    Think about it this way: Since the ptr[n] accesses a given element and is defined to be equivalent to *(ptr + n), we see that (ptr + n) without the * simply gets the address of ptr[n].

  2. The address converted to an integer is appears to be negative number, so adding a positive value decreases its magnitude. So the +2 changes to a +8 not a -8.

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

40 Comments

For the number 2. I was pretty wrong there it wasn't -8 but +8. For the number 1. So it is the same as ptr + n*sizeof(int) in this case ptr+2*sizeof(int) ? That is weird I thought that it goes with intuition like ptr + 2 and not ptr 2*sizeof(int). Good to know.
@Jackob2001 Yep. Pointer arithmetic carries an implicit *sizeof(*ptr).
I have one more question. Then if let's say -1931225192 contains value 3 then what -1931225191 contains ? Can I add in -1931225191 a different value ?
@Jackob2001 Undefined behavior. If you try to access an address that is not a multiple of the alignment requirement of the type, the behavior is undefined and the result is non-deterministic. Typically int is 4 bytes and also has 4 bytes alignment so if you try to access an int pointer that is not a multiple of 4, this can be problematic.
I've got one more and it is a last question because I came up with it now. What happens if I write *(ptr + 2*sizeof(int)) ? Will it then be *(ptr + (2*sizeof(int))*sizeof(int)) ? What I am trying to say is instead of *(ptr + 2) I want to change using instead of +2 the 2*sizeof(int) (because as you said this 2 is changes into 2*sizeof(int)) will it be the same or something will change ?
|
0

For starters these two calls of printf

printf("adress ptr = %d \n", ptr);   // 3
printf("adress ptr+2 = %d \n", (ptr+2)); // 4

have undefined behavior because there are used the incorrect conversion specifier d designed for integers to output pointers. You need to write

printf("adress ptr = %p \n", ( void * )ptr);   // 3
printf("adress ptr+2 = %p \n", ( void * )(ptr+2)); // 4

After this assignment

ptr = &x[2]; 

the pointer ptr points to the element x[2] of the array x. So dereferencing the pointer like *ptr you will get the element x[2] the value of which is equal to 3.

You may rewrite the above assignment the following way

ptr = x + 2; 

The expression ptr + 2 points to the second element of the array x after the element x[2] that is to the element x[4]. Dereferencing the expression *( ptr + 2 ) you will get the element x[4] the value of which is equal to 5.

The difference between the values of pointer expressions ptr and ptr + 2 is equal to 2 * sizeof( int ).

As you are using the incorrect conversion specifier to output pointers then you have negative numbers

adress ptr = -1931225192

and

adress ptr+2 = -1931225184

Nevrtheless the difference between these numbers is equal to 2 * sizeof( int ). As mentioned above you need to use the cirrect conversion specifier p to output valid values of the pointer expressions.

In general if you have an array for example x and a pointer ptr that is initialized by the address of the first element of the array x like for example

int x[5] = {1, 2, 3, 4, 5};
int* ptr = x;

then the expression ptr + i points to the i-th element of the array x. This is the so-called pointer arithmetic. A difference berween two points that point to elements of some array is equal to the number of elements between the elements pointed to by the pointers.

In this declaration

int* ptr = x;

the array designator x is implicitly converted to a pointer to its first element. This declaration actually is equivalent to

int* ptr = &x[0];

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.