0

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!

jiungsen
  • 23
  • 3

3 Answers3

3

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.

Community
  • 1
  • 1
Magisch
  • 7,312
  • 9
  • 36
  • 52
2

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.)

Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
2

As you may known the address of all variables,pointers are normally stored in Hexadecimal format.

If you directly convert 0x231c010(base 16) you get something like 0000 0010 0011 0001 1100 0000 0001 0000(base 2)

The conversion gives you a 32 bit value.

If you are familiar with the architecture of a computer you may know that all datapath(used to transfer data between various components inside a computer like ram to processor etc) use a device called "Sign Extender".

The C compiler actually produces only 32 bit values but these sign extender add extra 0's to it make it into 64 bit so the processor can work on it. After the processing is over the program gives you the 32 bit address even if you have a 64 bit OS. Unless you use a native 64 bit application(not a 64 bit compatable one) you will always get a 32 bit address.

Nirmal Raj
  • 729
  • 6
  • 18