This question already has an answer here:
I have the following question. Why is there a difference in the addresses of the two pointers in following example? This is the full code:
#include <stdio.h>
#include <stdlib.h>
void *mymalloc(size_t bytes){
void * ptr = malloc(bytes);
printf("Address1 = %zx\n",(size_t)&ptr);
return ptr;
}
void main (void)
{
unsigned char *bitv = mymalloc(5);
printf("Address2 = %zx\n",(size_t)&bitv);
}
Result:
Address1 = 7ffe150307f0
Address2 = 7ffe15030810
In your code you used to print pointer's address following code:
It doesn't print address of variabele it's pointing to, it prints address of pointer.
You could print address using '%p' format:
There's an example which explains printing addresses
So your code should be written like this:
(In addition to other answers, which you would read first and probably should help you more ...)
Read a good C programming book. Pointers and addresses are very difficult to explain, and I'm not even trying to. So the address of a pointer
&ptr
is generally not the same as the value of a pointer (however, you could codeptr= &ptr;
but you often don't want to do that)... Look also at the picture explaining virtual address space.Then read more documentation about
malloc
: malloc(3) Linux man page, this reference documentation, etc... Here is fast, standard conforming, but disappointing implementation ofmalloc
.read also documentation about
printf
: printf(3) man page,printf
reference, etc... It should mention%p
for printing pointers...Notice that you don't print a pointer (see Alk's answer), you don't even print its address (of an automatic variable on the call stack), you print some cast to
size_t
(which might not have the same bit width as a pointer, even if on my Linux/x86-64 it does).Read also more about C dynamic memory allocation and about pointer aliasing.
At last, read the C11 standard specification n1570.
(I can't believe why you would expect the two outputs to be the same; actually it could happen if a compiler is optimizing the call to
mymalloc
by inlining a tail call)So I did not expect the output to be the same in general. However, with
gcc -O2 antonis.c -o antonis
I've got (with a tiny modification of your code)....a surprise
However, if you declare the first
void *mymalloc(size_t bytes)
as astatic void*mymalloc(size_t bytes)
and compile with GCC 7 on Linux/Debian/x86-64 with optimizations enabled, you do get the same output; because the compiler inlined the call and used the same location forbitv
andptr
; here is the generated assembler code withgcc -S -O2 -fverbose-asm antonis.c
:BTW, if I compile your unmodified source (without
static
) withgcc -fwhole-program -O2 -S -fverbose-asm
I'm getting the same assembler as above. If you don't addstatic
and don't compile with-fwhole-program
the twoAdddress1
andAddress2
stay different.two run outputs
I run that
antonis
executable and got on the first time:and the second time:
If you want to guess why the outputs are different from one run to the next one, think of ASLR.
BTW, a very important notion when coding in C is that of undefined behavior (see also this and that answers and the references I gave there). You don't have any in your question (it is just unspecified behavior), but as my contrived answer shows, you should not expect a particular behavior in that precise case.
PS. I believe (but I am not entirely sure) that a standard conforming C implementation could output
Address1= hello world
and likewise forAddress2
. After all, the behavior ofprintf
with%p
is implementation defined. And surely you could get0xdeadbeef
for both. More seriously, an address is not always the same (of the same bitwidth) than asize_t
or anint
, and the standard definesintptr_t
in<stdint.h>
It's because you are printing the address of the pointer variable, not the pointer. Remove the ampersand (&) from
bitv
andptr
in your printfs.and
Also, use
%p
for pointers (and then don't cast to size_t)WHY?
In this line of code:
bitv
is a pointer and its value is the address of the newly allocated block of memory. But that address also needs to be stored, and&bitv
is the address of the where that value is stored. If you have two variables storing the same pointer, they will still each have their own address, which is why&ptr
and&bitv
have different values.But, as you expected,
ptr
andbitv
will have the same value when you change your code.Because the two pointers are two different pointer(-variable)s, each having it's own address.
The value those two pointer(-variable)s carry in fact are the same.
To prove this print their value (and not their address) by changing:
to be
and
to be