Why is length of memory address 12 hex digits long?


#1

Hi, I just started your book yesterday.

  1. Why are memory addresses for integers and floats 12 hex digits long?
  2. Why is the memory address for the function only 9 hex digits long?
  3. My Mac is a 64-bit machine. How would the memory address be different if it were 32 bits, and why?

My code:

[code]#include <stdio.h>

int main(int argc, const char * argv[]) {
int i = 17;
float j = 3.14159;
int *addressOfI = &i; //addressOfI is pointer
float *addressOfJ = &j;
printf(“i (int) stores its value at %p\n”, addressOfI);
printf(“j (float) stores its value at %p\n”, addressOfJ);
printf(“this function starts at %p\n”, main);
printf(“the int stored at addressOfI is %d\n”, *addressOfI); //dereferencing pointer
*addressOfI = 89; //change value at i’s address to 89
printf(“Now i is %d\n”, i);
printf(“An int is %zu bytes\n”, sizeof(int));
printf(“A pointer is %zu bytes\n”, sizeof(int *));
printf(“An int is %zu bytes\n”, sizeof(i));
printf(“A pointer is %zu bytes\n”, sizeof(addressOfI));
printf(“A float is %zu bytes\n”, sizeof(j));
return 0;
}[/code]

Output:

i (int) stores its value at 0x7fff5fbff86c <== 12 hex digits
j (float) stores its value at 0x7fff5fbff868 <== 12 hex digits
this function starts at 0x100000d50 <== 9 hex digits
the int stored at addressOfI is 17
Now i is 89
An int is 4 bytes
A pointer is 8 bytes
An int is 4 bytes
A pointer is 8 bytes
A float is 4 bytes
Program ended with exit code: 0

Also, this says that a 32-bit machine would have 8 hex digits. Why? (“An int is 32-bits wide.”)
http://en.wikipedia.org/wiki/Pointer_(computer_programming)#C_pointers

Example: 0x00008130 <== 8 hex digits

Please help. This is driving me crazy!


#2

Nathan Alday: "32 and 64 bit refer to the word size of the architecture. This is typically the size of the type that machine works best with… it’s underlying logic units expect inputs of this size.

Regarding 1 and 2, they’re just small values. On a 64 bit architecture, all of the memory addresses are 64 bits (each hex digit is four bits, so that’s 16 hex digits). They’re just dropping the leading zeros.

On a typical 32-bit architecture, there would only be 32 bits in a pointer, so only 8 hex digits. As a result, such an architecture can only use up to 4 GiB of RAM.

Some 32-bit architectures use what’s called Physical Address Extension (PAE), which allows for using more than 2^32 bytes for memory (a byte being the smallest addressable unit of memory) overall, but still no more than 4 GiB of memory per process."


Raymond Gan: "Thank you, Nathan! Good answer! However, I read that CPU makers only use 48-bits for addresses for a 64-bit system: stackoverflow.com/questions/6716 … ress-space

“CPU manufacturers took a shortcut. They use an instruction set which allows a full 64-bit address space, but current CPUs just only use the lower 48 bits. The alternative was wasting transistors on handling a bigger address space which wasn’t going to be needed for many years.”

I kept wondering why the size of the computer system was 4 times the number of hex digits.

12 hex digits * 4 = 48-bits (used for 64-bit system).
8 hex digits * 4 = 32-bit system.

The 4 comes from 2^4 = 16, expressing all hex digits from 0-15. (Why each hex digit is 4 bits.)

So the main function’s memory address really has 12 hex digits, but with 3 leading 0’s that are left out?

Is my explanation right?


#3

Nathan Alday: "Yep. They’re still storing them in 64 bit data types, though. That’s worth noting because (in theory) even when they implement full 64 bit addressing, programs compiled for the 48 bit addressing system may still work.

Specifically, if you do a sizeof( int*) for instance – asking the compiler for the number of bytes that a pointer to an int takes up, you’ll get 8 (8 bytes times 8 bits per byte = 64 bits.)

So if you did a bit operation on the pointer, say a bitwise NOT, you’d get you’d start off with a minimum of four 1s in the high bits. So you’d get a full 16 hex digits with the first 2 being “FF”. It’s worthing looking out for, because it means something has gone wrong, since on current architectures, a pointer should never have those 4 high bits set (set being equal to 1)

They just don’t use the upper 16 bits when addressing, so it’d actually be four nybbles (en.wikipedia.org/wiki/Nibble), and so you’d see FFFF in those two high bytes."


#4

Excellent! This really helped me understand pointers in C better:

The Ksplice Pointer Challenge
blogs.oracle.com/ksplice/entry/ … _challenge

What does this program print?

#include <stdio.h> int main() { int x[5]; printf("%p\n", x); printf("%p\n", x+1); printf("%p\n", &x); printf("%p\n", &x+1); return 0; }

Output:

0x7fff5fbff860

0x7fff5fbff864

0x7fff5fbff860

0x7fff5fbff874