How to print variable addresses in C?
Solution 1
You want to use %p
to print a pointer. From the spec:
p
The argument shall be a pointer tovoid
. The value of the pointer is converted to a sequence of printing characters, in an implementation-defined manner.
And don't forget the cast, e.g.
printf("%p\n",(void*)&a);
Solution 2
When you intend to print the memory address of any variable or a pointer, using %d
won't do the job and will cause some compilation errors, because you're trying to print out a number instead of an address, and even if it does work, you'd have an intent error, because a memory address is not a number. the value 0xbfc0d878
is surely not a number, but an address.
What you should use is %p
. e.g.,
#include<stdio.h>
int main(void) {
int a;
a = 5;
printf("The memory address of a is: %p\n", (void*) &a);
return 0;
}
Good luck!
Solution 3
To print the address of a variable, you need to use the %p
format. %d
is for signed integers. For example:
#include<stdio.h>
void main(void)
{
int a;
printf("Address is %p:",&a);
}
nambvarun
Updated on July 09, 2022Comments
-
nambvarun almost 2 years
When i run this code.
#include <stdio.h> void moo(int a, int *b); int main() { int x; int *y; x = 1; y = &x; printf("Address of x = %d, value of x = %d\n", &x, x); printf("Address of y = &d, value of y = %d, value of *y = %d\n", &y, y, *y); moo(9, y); } void moo(int a, int *b) { printf("Address of a = %d, value of a = %d\n", &a, a); printf("Address of b = %d, value of b = %d, value of *b = %d\n", &b, b, *b); }
I keep getting this error in my compiler.
/Volumes/MY USB/C Programming/Practice/addresses.c:16: warning: format ‘%d’ expects type ‘int’, but argument 2 has type ‘int *’ /Volumes/MY USB/C Programming/Practice/addresses.c:17: warning: format ‘%d’ expects type ‘int’, but argument 2 has type ‘int **’ /Volumes/MY USB/C Programming/Practice/addresses.c:17: warning: format ‘%d’ expects type ‘int’, but argument 3 has type ‘int *’ /Volumes/MY USB/C Programming/Practice/addresses.c: In function ‘moo’: /Volumes/MY USB/C Programming/Practice/addresses.c:23: warning: format ‘%d’ expects type ‘int’, but argument 2 has type ‘int *’ /Volumes/MY USB/C Programming/Practice/addresses.c:24: warning: format ‘%d’ expects type ‘int’, but argument 2 has type ‘int **’ /Volumes/MY USB/C Programming/Practice/addresses.c:24: warning: format ‘%d’ expects type ‘int’, but argument 3 has type ‘int *’
Could you help me?
Thanks
blargman
-
nambvarun over 13 yearsthat's what i originally thought but the tutorial on this website (cis.temple.edu/~ingargio/cis71/code/addresses.c) is telling me to use %d... is it wrong.
-
Carl Norum over 13 years@blargman, yes, it's wrong. You might be able to coerce things into working by typecasting, but since
%d
is for printing signed integers, it's probably not a good choice. -
pmg over 13 years+1: ... but for portability (and to follow the SHALL from the Standard) don't forget to cast the address.
printf("%p\n",(void*)&a);
-
Carl Norum over 13 years@pmg, is the cast necessary? I thought conversions to and from
void *
are safe and automatic in C (6.3.2.2 paragraph 1). -
nambvarun over 13 years@pmg what do u mean by portability?
-
hlovdal over 13 yearsBy portability is meant the possibility to compile/run the program with different compilers/operating systems/computers. en.wikipedia.org/wiki/Portability_%28software%29
-
pmg over 13 yearsThanks @hlovdal; that is indeed what I mean.
-
pmg over 13 years@Carl: in variadic functions the compiler cannot check the types of arguments against the expected types. The cast to
void*
is not automatic: what is automatic in variadic functions is a few low-range integers toint
, andfloat
todouble
. -
Carl Norum over 13 years@pmg - that makes sense. I found more about it in 6.5.2.2 after asking here. Have you ever worked on a machine where
void *
was incompatible with any other pointer types? -
hlovdal over 13 years@Carl: And similar to variadic functions, if you happen to call a function which the compiler have not seen a prototype for, it will assume int for all parameters, and sizeo(int) might be different from sizeof(void *), so it is important to be aware of these two cases. This specifically also applies to
NULL
which might be defined as just0
which is of type int. E.g.ret = execlp("ls", "ls", "-l", (void *)NULL);
. -
pmg over 13 years@Carl: no, I have only worked with well-behaved machines. In ancient days, with TurboC (or whatever) I had a few programs where function pointers and data pointers had different size:
sizeof (void(*)()) != sizeof (void*)
-
hlovdal over 13 yearsActually the man page for execlp also says this: "The list of arguments must be terminated by a NULL pointer, and, since these are variadic functions, this pointer must be cast (char *) NULL."
-
nambvarun over 13 years@pmg where do u learn these fascinating concepts? Could u please reference me to some books. Thanks for the fascinating discussion.
-
Keith Thompson about 11 yearsThe value
0xbfc0d878
is a number.(void*)0xbfc0d878
is not. And%p
is likely to use a human-readable representation that looks like a number (typically hex) but that doesn't mean pointers are numbers. (BTW, the question was answered more than 2 years ago.) -
Alexander over 6 yearsWhile this code may answer the question, providing additional context regarding how and why it solves the problem would improve the answer's long-term value.
-
Cristian Gutu over 5 yearsWhy do we have to cast to
(void*)
?