Q:

Why is some file pointer have 28-bit address on a 64-bit OS?

I'm a novice on programming and there are one unimportant but confusing problem that bothers me.
Let me post my code first:
FILE *fp;
int i;

fp=fopen("test_data.txt", "r");
printf("i's address=%p\n", &i);
printf("fp's address =%p\n", fp);
printf("stdout's address=%p\n", stdout);
close(fp);

The output is:
i's address=0x7ffd038ab8cc
fp's address=0x231c010
stdout's address=0x7fbb2e4f7980

My problem is that why is the fp's address 28-bit? Shouldn't it be the same as normal variables and standard output (48-bit)?
I use GCC on 64-bit Ubuntu Linux.
Thanks for your answers! 

A:

The most likely case here is that your file adress simply starts with zeros, which are omitted by default. 
Edit: Here is a question that points to a similar kind of problem. 

A:

fopen is likely to call malloc to get its FILE* handle.
And some implementations of malloc are allocating "small" objects and "large" objects differently - in different address space segments (obtained with mmap(2) or some other system call, listed in syscalls(2)...)
On some implementations, stdout is a pointer to some static data...
Also, you probably have ASLR enabled...
You might investigate by using pmap(1) on your running process. See also proc(5); if you have time to spare, read sequentially lines from /proc/self/maps inside your program, and copy them to stdout ; try also cat /proc/$$/maps to understand what is your shell's virtual address space.
You could also strace(1) your program to understand the many system calls it is doing....
But you really should not bother. From a C perspective, addresses are more or less random (unless you dive into implementation details)
(On some x86-64 processors, there are really only 48 bits of address, with the highest 16 bits all zeros or all ones.)

