1

I ran into a pointer dereferencing problem.

In C, &a means the address of a. If a is a pointer ,then &a simply means the address of that pointer.

So if we have:

char ptr [] = "abcd"

ptr should be a pointer pointing to the first character, which is 'a'. therefore,

&ptr

should be the address of ptr, which is different than the address of 'a'. However, when I tried the following code I got really confused:

int main()
{
    char a [] = "abcd";

    printf("0x%X 0x%X", a, &a);

}

Output: 0xBF7E62AB 0xBF7E62AB

Can someone explain why a and &a have the same value? Based on my understanding they should be different. thanks in advance

turtlesoup
  • 3,188
  • 10
  • 36
  • 50
  • 2
    `ptr` is not a pointer. It's an array. You can tell because there's no `*` in your code, but a big fat `[]`. – Kerrek SB Oct 22 '13 at 20:45
  • 1
    Try printing the values of `a+1` and `&a+1` and you will see a difference. http://web.torek.net/torek/c/pa.html answers your question very nicely, BTW. – Alok Singhal Oct 22 '13 at 21:13
  • 1
    @KerrekSB ***BUT HEY AN ARRAY IZ JUST A POINTER IZNT IT???*** –  Oct 22 '13 at 21:18
  • 3
    @H2CO3: Don't troll - the "iznt it" is a dead giveaway. The real pro never questions his own assumptions but self-righteously takes them as fact, and then furiously berates reality for not conforming to his conclusions. – Kerrek SB Oct 22 '13 at 21:21
  • @KerrekSB I hope that was sarcasm. :) "The real pro never questions their own opinion"... how many times I've seen this behavior... –  Oct 22 '13 at 21:23
  • possible duplicate of [Is array name a pointer in C?](http://stackoverflow.com/questions/1641957/is-array-name-a-pointer-in-c) – n. m. could be an AI Oct 23 '13 at 03:03

6 Answers6

3

So if we have: char ptr [] = "abcd", ptr should be a pointer pointing to the first character.

No. Not at all.

ptr is an array. And an array is not a pointer.

Indeed, if you declared ptr as a real pointer, then you would get the expected behavior:

const char *ptr = "abcd";
printf("ptr = %p, &ptr = %p\n", (void *)ptr, (void *)&ptr);

As to why the address of the array is the same as the address of its first element: it's quite logical. The array represents a contiguous sequence of elements. The address of the array is where the array begins in memory. It begins where its first element begins. So, the address of the first element is (rather "can be" -- the standard does not mandate this behavior) the same as the address of the array itself.

+-----------+-----------+- - - -
| element 1 | element 2 |
+-----------+-----------+- - - -
^ start of array
^ start of first element
  • Do you need to cast to void there? – detly Oct 22 '13 at 21:51
  • 2
    @detly Yes, absolutely, else it's undefined behavior (`%p` expects a pointer to void, and in addition, `printf()` is variadic, so there's no implicit conversion that usually would be done.) (in practice, this "works" without a cast, though, and in fact, I'm a great opponent of casting stuff, especially in the case of `void *`, but unfortunately, this is a case -- the only case I know of - that it's obligatory.) –  Oct 22 '13 at 22:37
2

Can someone explain why a and &a have the same value? Based on my understanding they should be different.

In the statement

  printf("0x%X 0x%X", a, &a);  

Both a and &a are of different types. a is of char * type (after decay) while &a is of char (*)[5] type.
a decays to a pointer to the first element, therefore a is the address of first element of the string. While &a is the address of the string "abcd" and it is equal to the address of first element.

haccks
  • 104,019
  • 25
  • 176
  • 264
0

An array is not a pointer. That's right when you said &p is the address of the pointer, if p is definied like this:

char *p;

An array is different and don't has exactly the same behavior.

With the arrays:

char a[] = "abc";, &a[0] is the address of the first element in your array, which is the same as a.

nouney
  • 4,363
  • 19
  • 31
0

char a[] = "abcd" does not declare a pointer a to "abcd" but an array. Even if an array can decay to a pointer, it is a different type for which &a and a yield the same address.

Basically a yields the address to the first element of the array, so it is equivalent to &a (and to &a[0]).

Jack
  • 131,802
  • 30
  • 241
  • 343
  • i can do printf(%x,*a), and that will print 'a' in hex, which is the first element in that array, and that behaves identical to a pointer. So if I was given something like a, there is no way to tell whether it's an array or a pointer, but their return values are different? that doesn't make complete sense to me. – turtlesoup Oct 22 '13 at 20:53
  • This is because when passing an array name to `printf`, it will decays to pointer to first element. That's why dereferencing it giving you `a`. But that doesn't mean that an array is a pointer. – haccks Oct 22 '13 at 20:59
  • Say I declare a function and some user accidentally passes in an array instead of a pointer. In that case, is there a way to tell apart an array and a pointer? Or seg fault is the only solution? :\ – turtlesoup Oct 22 '13 at 21:19
  • @turtlesoup I don't see how a "seg fault" is related. Once you pass an array to a function, there's no way the called function could tell if you passed an array or a pointer. The difference is only apparent from *outside* of the function. –  Oct 22 '13 at 21:21
  • @turtlesoup If you pass an array to a function, it is automatically converted to a pointer to the first element of the array. – This isn't my real name Oct 24 '13 at 16:24
0

Arrays will always reference the location where it is stored in memory, that's why when you print a, it gives you the address where it is, which is equal to getting the pointer pointing at the array (&a)

MangO_O
  • 393
  • 1
  • 3
  • 15
0

To get the behaveour you seek change

char a [] = "abcd";

to

char *a  = strdup("abcd");

or for a readonly string

const char *a  = "abcd";

You will then get a different address for a and &a.

When passing an array to a function, the array gets converted to a pointer. With your original program try

printf("%d %d\n",sizeof(a),sizof(&a));

The first will vary with the size of the string, the second will be based on the pointer size on your machine.

Robert Jacobs
  • 3,266
  • 1
  • 20
  • 30
  • @H2CO3 in C, string literals have type `char []`, not `const char []`, right? – Alok Singhal Oct 22 '13 at 21:27
  • @AlokSinghal That's exactly right. However, they are not modifiable (despite the fact that they are not composed of `const` elements), and the conversion from a string literal to `char *` is deprecated (at least if we can believe `clang` and `gcc`). So, it's good practice to point to string literals using a pointer-to-`const`. (In C++, they've got this right, and there, string literals have type `const char []`.) –  Oct 22 '13 at 21:29