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

6
  • 2
    ptr is not a pointer. It's an array. You can tell because there's no * in your code, but a big fat []. Commented Oct 22, 2013 at 20:45
  • 1
    Try printing the values of a+1 and &a+1 and you will see a difference. web.torek.net/torek/c/pa.html answers your question very nicely, BTW. Commented Oct 22, 2013 at 21:13
  • 1
    @KerrekSB BUT HEY AN ARRAY IZ JUST A POINTER IZNT IT??? Commented Oct 22, 2013 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. Commented Oct 22, 2013 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... Commented Oct 22, 2013 at 21:23

6 Answers 6

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
Sign up to request clarification or add additional context in comments.

2 Comments

Do you need to cast to void there?
@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.)
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.

3 Comments

&a is not of type char **. It's of type char (*)[5].
@H2CO3; That was typo.
@haccks I know that feeling :)
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.

Comments

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]).

5 Comments

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.
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.
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 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.
@turtlesoup If you pass an array to a function, it is automatically converted to a pointer to the first element of the array.
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)

Comments

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.

2 Comments

@H2CO3 in C, string literals have type char [], not const char [], right?
@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 [].)

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.