Reputation: 8547
I am new to pointers in C language. I understand that a pointer stores the address from the memory and not the value.
If I initialize a regular variable with a value, that value is getting stored in my memory. However, the systems has to store where my value is, right? So isn't the system having a pointer to that variable aswell?
int b = 3;
If I access b
, the system has to know the address where the "3" can be found right? Or am I mistaken?
I know that variables are on the stack and pointers can point to the heap/stack.
Upvotes: 1
Views: 2624
Reputation: 6068
Memory addresses are building blocks. They are can be used in multiple ways:
int b = 3;
.Given the instructions
int b = 3;
...
printf("%d\n", b);
The compiler has to reference b
's address in order to give it to printf()
.
I won't repeat the other answers here, they do well in explaining how that works.
Unlike other parts of a program's execution, the heap is only accessible through pointers:
int *p = malloc(ints_to_alloc * sizeof(int));
The only way to obtain some unknown amount of int
s that can live across any particular function execution is to allocate them on the heap.
Pointers can also be used to implement indirection, no matter where:
typedef struct { int x; int y; } example_t;
example_t stack_e;
example_t heap_e = malloc(sizeof(example_t));
example_t *e;
if (some_global_var == 1)
e = heap_e;
else
e = &stack_e;
// do something with e
Upvotes: 1
Reputation: 224310
When the compiler writes instructions for a program, it does not need to know “the address” of an object, for two reasons:
For the stack in particular, there is a register called the stack pointer. When the program loader loads the program to be executed, it sets the stack pointer. Then objects on the stack can be referred to via constant offsets from the stack pointer. When the compiler sees definitions in a function such as int q
or double x
, it plans some space on the stack where those will be stored and write instructions that refer to them as “8 bytes above where the stack pointer points,” for example. (There may also be a frame pointer that points to part of the stack, so objects may be referred to relative to the frame pointer instead of the stack pointer.)
When your program takes the address of an object on the stack, such as &x
, the program would compute this by calculating the contents of the stack pointer plus the offset to x
.
For object with static storage duration, such as an int z;
defined outside of any function, the compiler plans some space for them in a data section of memory. When the compiler is writing the object file, it includes descriptions of the symbols it wants in the data section, including where those symbols should be in the data section. Then, in the instructions it writes, it puts placeholder information that says “this instruction is referring to symbol z
from the data section.” When the linker links this program or the program loader loads it, it will decide where the data section is going to be in memory. Then it adjusts those instructions to put the correct address in them.
Sometimes instructions will contain complete addresses, and the linker or loader adjusts them when it decides the final address. Sometimes instructions will refer to objects through offsets from registers, similarly to the stack. In that case, the loader will set some register to point to the beginning of the data section or another reference point, and the instructions will refer to static objects like z
using that register plus an offset.
There are also further schemes available, such as having the program look up some addresses in a table. But, overall, the compiler does not need additional pointers to point to objects. It has ways of referring to objects directly in the instructions, without always creating extra pointers.
Upvotes: 1
Reputation: 1600
Say the program is:
int main()
{
int i=8;
int j;
return 0;
}
When function main()
is called, a stack space like this is allocated for further operation:
+-------------------------------------- +
| function | variable | value | address |
+---------------------------------------+
| main() | i | 8 | 0Xabc |
| | j | ? | 0Xbca |
+---------------------------------------+
The stack space is allocated but compiler just knows the offset and the base of the stack frame & with the help of that offset compiler locates the local variable. There is no pointer involved to save the address to locate the variable.
Upvotes: 3
Reputation: 5512
It is the compiler's job to figure out where to store a variable. A variable has a couple of things associated with it:
A compiler implicitly (most of the time) manages the first and the last two. So when you declare a variable inside a function, say int x;
compiler will allocate some space on the stack and remember the offset from ESP for that variable. The lifetime is the function body and ends when the function returns.
The mapping is not pointers, but yes, the system knows due to the nature of generated code where a local variable resides.
Similar reasoning applies for global variables, compiler is managing their allocation/storage.
P.S.: Above assumes x86/x64 instruction set. Also assumes no optimizations whatsoever, things could reside in registers etc.
P.P.S.: Think of a pointer as another integer variable, but this time the value it holds has a special meaning. It is an offset into the memory, the address. Again, I am simplifying things like addressing modes. You will eventually read about these things.
Upvotes: 2