Home > Software design >  Width in bytes of a pointer in C
Width in bytes of a pointer in C

Time:10-06

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.

  • Related