This question already has an answer here:
- Pointer to pointer clarification 16 answers
IMPORTANT: This tried to ask too many things at once and was misleading because I wrote it under a false assumption about how pointers can be used, and it ended up just looking like a duplicate. Please see this instead: How are variables tied to their values in C?
Let's consider that there is a value 4
at address 0001
, and then we assign the address 0001
to the variable num
. We could visualize this as two tables:
VARIABLE|ADDRESS ADDRESS|VALUE
num |0001 0001 |4
From what I understand, this would be the end product of the following code:
int temp = 4;
int * num = &temp;
However, what is going on at the first line, int temp = 4;
? Does that first line produce something like this?
VARIABLE|ADDRESS ADDRESS|VALUE
| temp |4
And how do pointers to pointers work? Would the code:
int temp = 4;
int * num = &temp;
int ** pnum = #
produce this?
VARIABLE|ADDRESS ADDRESS|VALUE
num |0001 0001 |4
pnum |0002 0002 |0001
What is the right way to think of this? What is actually going on under the hood? Also, how does this change when a struct is stored instead of a number?
I understand that the above examples are probably entirely incorrect; they were simply to contextualize my question.
Not all variables need to have an address in the memory system, some variables are short lived enough that they can live their whole life-span in registers. In such a case, they get allocated (renamed) by the compiler to things like
eax
,ebx
orr1
,r2
. Registers are slots in the CPU that can hold variable contents.Because lots of architecture have limited register numbers (8 virtual (visible to the machine language) registers in x86-64, 256 registers in IA64...) the rest of the variables get allocated (compiled) to an address in memory, which will always be on the stack. The stack (tracked by
esp
register, a special register) is a last in first out allocator with support of the operating system (memory pages get live as it grows) so the compiler just has to take the current stack pointer and increment it by the size of the variable to allocate, and that's the variable's address.Value assignation, like in the first case you demonstrated, is done by issuing a
mov
assembly command with a hardcoded value, the constant thus exist in the memory space of the program. Which means the value comes from the instruction itself. (L1:inst cache->fetcher->CPU pipeline->mov->STORE pipeline->L1:data cache)The rest works like you sensed.