0

Here's the code:

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

void foo(int* ptr) {
    printf("ptr is %x\n", ptr);
}

void main() {
    int* ptr = (int*)malloc(sizeof(int));
    printf("ptr is %x\n", ptr);
    foo(ptr);
    free(ptr);
}

...And he're the output:

ptr is 0x007446c0
ptr is 0x00000000

...And here's the question:
Why is this happening to me???

Yehuda Shapira
  • 8,460
  • 5
  • 44
  • 66
  • at the risk of being the same broken record everyone else is, don't cast malloc() in C -- use "int* ptr = malloc( sizeof( int ) );" – K Scott Piel Mar 22 '13 at 13:04
  • @ Jacob Spire See this: http://stackoverflow.com/questions/1565496/specifically-whats-dangerous-about-casting-the-result-of-malloc – K Scott Piel Mar 22 '13 at 13:07
  • @JacobSpire I tried your program as is on `Visual C++ 2010 Express` and I got correct prints. Are you sure you got the second number as 0x0? – Ganesh Mar 22 '13 at 13:11
  • @Ganesh - The values you see can be different because of modifiable lvalue's answer, passing the wrong format specificer is UB. – Mike Mar 22 '13 at 13:13
  • @Mike.. Thanks.. why should a `%x` format specifier print `0x0` instead of some other `junk` value? – Ganesh Mar 22 '13 at 13:16
  • @Ganesh - UB means undefined behavior, undefined behavior means anything can happen. So it's possible that you'd see 0x0 as Jacob did, or the correct value as you did, or even a banana. There's no way of knowing what will happen. – Mike Mar 22 '13 at 13:26

2 Answers2

3

This happens because %x in printf expects an unsigned integer, not a pointer.

Here is how to fix your program to get the behavior that you want:

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

void foo(int* ptr) {
    printf("ptr is %p\n", (void*)ptr);
}

int main() {
    int* ptr = malloc(sizeof(int));
    printf("ptr is %p\n", (void*)ptr);
    foo(ptr);
    free(ptr);
    return 0;
}

Here is a link to ideone; the run produces an expected result:

ptr is 0x8fa3008
ptr is 0x8fa3008
Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • I had tried the original program with `%x` and it works fine without any issues. I tried on both `gcc (MinGW)` and `Visual C++ 2010 Express` and it was successful on both environments. Why should `%x` print 0x0 and not some junk number? – Ganesh Mar 22 '13 at 13:14
  • 1
    @Ganesh That's the danger of undefined behavior: sometimes it produces "the right thing". One reason why `%x` could print zero would be a 64-bit address: the upper half could very well be zero. – Sergey Kalinichenko Mar 22 '13 at 13:20
1

Because your program invokes undefined behaviour, I presume. Here's what I think you meant:

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

void foo(int* ptr) {
    printf("ptr is %p\n", (void *) ptr); /* %x tells printf to expect an unsigned int. ptr is not an unsigned int. %p tells printf to expect a void *, which looks a little better, yeh? */
}

int main() { /* main ALWAYS returns int... ALWAYS! */
    int* ptr = malloc(sizeof(int)); /* There is no need to cast malloc. Stop using a C++ compiler to compile C. */
    printf("ptr is %p\n", (void *) ptr);
    foo(ptr);
    free(ptr);
}

Does that fix your problem?

autistic
  • 1
  • 3
  • 35
  • 80