-4

So imagine I have this

main() {
    int a = 5;
    int *p;
    printf("p: %d", (void*)p);
}

Why would I have to cast the *p in the printf statement? But if I do this...

p = &a;
printf("p: %d", *p);

This time I don't have to cast?

So my question is that do I need to cast void everytime to a null pointer?

  • I'm rusty with C but i'm going to take a stab and say because you implicitly initialized the pointer with the `p= &p;` statement? – Brandt Solovij Oct 06 '15 at 19:09
  • I meant to say p = &a; –  Oct 06 '15 at 19:10
  • 1
    To print the address of a pointer you sould use `%p` instead of `%d`, the `%p` format expect a cast `(void *)` – David Ranieri Oct 06 '15 at 19:12
  • I don't want to get the address of the pointer. I want to dereference it so I retrieve what is stored in memory. –  Oct 06 '15 at 19:14
  • @AlterMann what happens when I cast it with void? –  Oct 06 '15 at 19:17
  • @YusufJama, you are invoking undefined behavior, you can not print an address with `%d` – David Ranieri Oct 06 '15 at 19:18
  • @AlterMann no it is a reference to an int..that is what the pointer is. So when I am saying (void *)p in the first print statement, it returns a value? As in I am not worried about the memory address...I want the value stored in that memory location. –  Oct 06 '15 at 19:20
  • Is a reference to an int, yes, but `p` is not initialized, so you can not dereference the pointer – David Ranieri Oct 06 '15 at 19:21
  • Ok I get that so far BUT what does (void *) mean? –  Oct 06 '15 at 19:24
  • 2
    You might like to read on the type `void`, on how to define a pointer, on the de-reference operator `*` and on `printf()` in general and its conversion specifiers in particular, if then any issues are still open feel free to come back. Casting also might be of your interest. – alk Oct 06 '15 at 19:25
  • 1
    And btw, I do not see any null-pointers in your question. – alk Oct 06 '15 at 19:28
  • Following @alk, OP might be interested in this SO question: http://stackoverflow.com/questions/3581585/whats-the-difference-between-a-null-pointer-and-a-void-pointer – Weather Vane Oct 06 '15 at 19:37

2 Answers2

2

In the first example you are printing the value of the pointer itself, but are using the wrong format specifier.

printf("p: %d", (void*)p);

should be

printf("p: %p", (void*)p);

The reason is, an int specified by %d might not be the same size as a pointer. The reason for the cast, is because %p prints the value of a void* pointer. But note: in your example int *p is unintialised, so printing its value is useless.

In the second example you are printing the value pointed to, by the pointer, and no cast is necessary, because the types are consistent.

printf("p: %d", *p);
Weather Vane
  • 33,872
  • 7
  • 36
  • 56
  • What I want is what is stored in memory..not the memory address. I am trying to dereference it...are you saying I can't dereference a null pointer? –  Oct 06 '15 at 19:25
  • 1
    @YusufJama yes. A `void*` pointer points to an indeterminate object, so you cannot dereference it. Functions such as `malloc()` return a `void*` pointer so that it can be assigned to any data type. But conversely, `printf` using the format spec `%p` needs a `void*` pointer, by definition. – Weather Vane Oct 06 '15 at 19:27
  • What if the pointer is set as p = &a? Why wouldn't I need a cast void? –  Oct 06 '15 at 19:29
  • "Deferencing" a pointer is fetching the thing it points to. If it's not pointing to anything (either by virtue of being a void * type or by having a NULL value), then you can't fetch what doesn't exist. – Lee Daniel Crocker Oct 06 '15 at 19:30
  • @YusufJama as explained, if you are using `int` type all is consistent, no cast required. But to print the pointer address value itself, it has to be cast to `void*`, although you *might* "get away with" not doing so, or using a different format specifier, and such might "work" on your platform, happily, but not by design. – Weather Vane Oct 06 '15 at 19:32
  • Ok so what is what is stored inside what that pointer points to. Let's say that the pointer is not initialized. If I cast with void*, why am I getting a value returned? Is that a random memory location? –  Oct 06 '15 at 19:40
  • *random* is not quite the right word because that's a valid concept. Perhaps "spurious". If the pointer is not initialised, anything you do with it is **undefined behaviour**. – Weather Vane Oct 06 '15 at 19:41
  • Ok that makes sense...even though it is not initialized, it could be whatever was stored in memory previously that is being returned. Would that be a way of saying it? –  Oct 06 '15 at 19:43
  • Well yes, there was *some value* from some previous use. But it's not useful. In fact using it, may cause all sorts of trouble, especially with a pointer. – Weather Vane Oct 06 '15 at 19:44
0

To print out pointer values (NULL or otherwise), you must use the %p conversion specifier, which expects its corresponding argument to have type void *:

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

This is probably the only time in C you need to explicitly cast a pointer value to void * (if it isn't already void *, anyway). The reason why is a combination of how printf reads its arguments, default type promotions in variadic functions, and a couple of other things that I have yet to figure out how to explain well.

Note that you are casting the value of p (the pointer), not the thing that it points to.

In the second print statement,

printf("*p = %d\n", *p );

you are printing the value of the thing that p points to, which is an integer. The expression *p has type int, which is what the %d conversion specifier expects.

John Bode
  • 119,563
  • 19
  • 122
  • 198