I'm new to dynamic and static allocation and I noticed a strange behaviour. I made the following code snippet :
#include ...
int main(void){
int i ;
printf(" using amesand :%p\n", &i);
int *j = malloc(sizeof(*j)) ;
printf(" using malloc :%p\n", j)
}
which then compiles and produces :
using amesand :0x7ffc0128695c
using malloc :0x6686b0
I have read somewhere that
all pointers have the same width within the same implementation.
Can someone explain why is the pointer returned by malloc() only 3 bytes long ?
CodePudding user response:
Do determine the width of pointers use the sizeof
operator, For example
int i ;
printf(" using amesand :%zu\n", sizeof( &i ));
int *j = malloc(sizeof(*j)) ;
printf(" using malloc :%zu\n", sizeof( j) );
As for this output then addresses can have different values depending where the corresponding memory was allocated. And using the conversion specifier %p
generates usually (as in your case) an output where leading zeroes are skipped.
CodePudding user response:
all pointers have the same width within the same implementation.
Yes for strictly conforming C programs at least. There's common non-standard extensions where larger pointers are mixed with ordinary ones, usually with the non-standard keyword far
.
However that isn't the problem here, but merely your use of printf
. By default it removes leading zeroes. Not only for hex but for any number. printf("%d", 1)
prints 1
right? And not 0000000001
just because int
happens to be 4 bytes = 10 decimal digits. Pointers and hex are no different, leading zeroes are removed by default until you tell the function otherwise.
If you wish to print a hex number corresponding to the size of the pointer, you'd use %.16p
for 16 digits = 8 byte large pointers. Or variably/portably, like this:
printf(" using malloc :%.*p\n", sizeof(j)*2, j);
Corrected example tested on x86_64 Linux:
#include <stdio.h>
#include <stdlib.h>
int main(void){
int i ;
printf(" using amesand:\t%.*p\n", sizeof(&i)*2, &i);
int *j = malloc(sizeof(*j)) ;
printf(" using malloc:\t%.*p\n", sizeof(j)*2, j);
}
Output:
using amesand: 0x00007ffe8710871c
using malloc: 0x0000000000ed82b0
Regarding why the different memory types have different addresses, see this:
A program uses different regions of memory for static objects, automatic objects, and dynamically allocated objects
CodePudding user response:
With %p
, your C implementation simply omits leading zeros from pointer values.
Printing “0x6686b0” does not indicate the pointer is three bytes long; it merely indicates the value is 6686b016, which equals 006686b016, 00000000006686b016, or 0000000000000000000000000000000006686b016. Leading zeros have been omitted.