0

I just started learning about pointers and I'm someone who gets stuck in the details. I understand that when we add an integer to a pointer, it offsets the pointer by its size which is 4. Same for another type with size m. But I don't get why the address of first element changes in the following operations.

I did the following operation

#include <stdio.h>

int main()
{
    int arr[] = {10,20,30,40,50};
    int *ptr = arr;
    int i;
    for(i=0;i<5;i++)
    {

        printf("%d\n", ptr);
        ptr++;
    }
    return 0;
}

and got the following as output:

6422016 6422020 6422024 6422028 6422032

but when I changed the loop like this:

for(i=0;i<5;i++)
    {

        printf("%d\n", ptr+i);

    }

The output is this:

6422000 6422004 6422008 6422012 6422016

Why do I get different addresses? I thought at least the first address would be same. Does ptr+i and ptr++ do different things?

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
DevKara
  • 1
  • 1
  • 1
    your kernel most likely supports [ASLR](https://en.wikipedia.org/wiki/Address_space_layout_randomization) and has it enabled. Also, the [correct way to `printf` an address](https://stackoverflow.com/questions/197757/printing-pointers-in-c) is with the `"%p"` format specifier, casting the pointer to a `void*`. – yano Mar 22 '23 at 17:33

2 Answers2

3

The exact addresses used for any given variable is an implementation detail of the compiler. There's no guarantee that a variable will reside at the same address if the code is changed and recompiled. In fact, there's no guarantee that the address will be the same each time you run the same program.

The only thing you can be sure of is that addresses of elements of an array have increasing addresses with increasing indices.

dbush
  • 205,898
  • 23
  • 218
  • 273
  • Re “an array have increasing addresses with increasing indices”: The C standard guarantees `i` < `j` implies `&a[i] < &a[j]` evaluates as true within array bounds but not that any integer or `%p` representation of them or the actual machine addresses will be increasing. It could be useful for a C implementation to reverse the algorithm order of array elements because it could mitigate the consequences of buffer overflows. – Eric Postpischil Mar 22 '23 at 19:09
0

To output a pointer you need to use conversion specifier p instead of d

printf( "%p\n", ( void * )ptr );

As for your question then the initial address of the array can be changed in different runs of the program.

To get the same results of the for loops just include them both in one program like for example

#include <stdio.h>

int main( void )
{
    enum { N = 5 };
    int arr[N] = { 10, 20, 30, 40,50 };
    int *ptr = arr;

    for ( int i = 0; i < N; i++ )
    {
        printf("%p\n", ( void * )ptr );
        ptr++;
    }

    putchar( '\n' );

    ptr = arr;

    for ( int i = 0; i < N; i++ )
    {
        printf( "%p\n", ( void * )( ptr + i ) );
    }

    return 0;
}

In fact using the variable i in the first for loop is redundant. You could rewrite the loop the following way

for ( ; ptr < arr + N; ++ptr )
{
    printf( "%p\n", ( void * )ptr );
}
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335