0
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv)
{
    struct s1 {
        char *z;
        int i;
        struct s1 *p;
    };
    struct s1 *ptr;
    static struct s1 a[] = {
        {"Nagpur", 1, a + 1},
        {"Raipur", 2, a + 2},
        {"Kanpur", 3, a}
    };
    ptr = a;

    printf("%p\n", a[0]);
    printf("%p\n", a[1]);
    printf("%p\n", a[2]);
    printf("%p\n", ptr);
    printf("%p\n", a[2].p);
    printf("%p\n", a[1].p->p);
    printf("%p\n", a);

    return EXIT_SUCCESS;
}

Whenever we have an array, suppose we call it a[10], then the address of a or a[0] are equal. But in the above case, the address of a and that of a[0] is different. I can't figure out why?

  • Don't you think the output of your program (and compiler) would be helpful? – Jonathon Reinhart Mar 11 '15 at 04:52
  • I checked the output but I still cannot figure out why does it give such an output. Don't you think if I print out `ptr` it should give same result as `a[0]`? – Gurucharan Sharma Mar 11 '15 at 04:54
  • Alweays add a [cast to `void *`](http://stackoverflow.com/questions/26751722/usage-of-void-pointers-across-different-platforms/26751747#26751747) before printing data pointers. `printf("%p\n", (void *)&a[0]);`. Also compile with `-W -Wall -O2` for your answer. – Mohit Jain Mar 11 '15 at 04:54
  • well, I would strongly suggest NOT using any optimization so no '-O2' however, I would really like to see the output from this program. That output would greatly help in the debugging process. – user3629249 Mar 11 '15 at 05:02
  • the printf() calls with the a[x] parameter will not print addresses but rather the contents of that offset. This line segment: 'then the address of a or a[0] are equal' is not true. However, then the address of a and the address of a[0] are equal is true. – user3629249 Mar 11 '15 at 05:05

5 Answers5

3

What you're passing to printf() here is the structure itself, not a pointer to it:

printf("%p\n", a[0]);

The behavior of this code is poorly defined. (In practice, it will typically end up printing the first element of the structure, but this may not be consistent.) What you probably want is:

printf("%p\n", &a[0]);
               ^
  • What about `a`. `&a` and `a` both give the same result but `*a` gives same result as `a[0]`. Please elaborate. – Gurucharan Sharma Mar 11 '15 at 05:02
  • 1
    @GurucharanSharma This is a well-documented effect of arrays decaying to pointers. Please see: http://www.lysator.liu.se/c/c-faq/c-2.html –  Mar 11 '15 at 05:18
1

If you had compiled with warnings enabled (e.g. gcc -Wall -Werror), you would see that this line:

printf("%p\n", a[0]);

is invalid:

ptr.c:20:5: error: format ‘%p’ expects argument of type ‘void *’, but
argument 2 has type ‘struct s1’ [-Werror=format=]
     printf("%p\n", a[0]);
     ^

You're taking the 0th element of that structure, or in other words, dereferencing a, and passing a struct s1 by value to printf, who is doing like you said, and interpreting it as a pointer.

If you instead take the address of the first element of the array, you'll see that they are indeed, at the same address:

printf("%p\n", &a[0]);
Jonathon Reinhart
  • 132,704
  • 33
  • 254
  • 328
0

The reason why both are different is when you print a, its just reference, whereas a[0] is used to de-reference. Try printf("%p\n",&a[0]).

user3451261
  • 676
  • 1
  • 7
  • 4
0

the printf() calls with the a[x] parameter will not print addresses but rather the contents of that offset. This line segment: 'then the address of a or a[0] are equal' is not true. However, then the address of a and the address of a[0] are equal is true. The '%p' format converter is only for addresses. so the code needs to use addresses, not the contents.

suggest using something like:

printf("%p\n", &a[0]); 
printf("%p\n", &a[1]);
printf("%p\n", &a[2]);
printf("%p\n", ptr);
printf("%p\n", a[2].p);
printf("%p\n", a[1].p->p);
printf("%p\n", a);
user3629249
  • 16,402
  • 1
  • 16
  • 17
0

you are assigning addresses of strings (e.g. "nagpur") char pointer. these strings will be present in code section. so "z" will be having addresses of those strings and you are trying to print those by printing a[0]. you should print &a[0] instead. a[0] is similar operation to *(a+0). so if you want to print its address you should use & operator.

Chintan Patel
  • 310
  • 1
  • 2
  • 11