Where are addresses of pointers stored in C?

后端 未结 5 1869
慢半拍i
慢半拍i 2021-02-10 10:01

I\'m learning C and currently learn about pointers. I understand the principle of storing the address of a byte in memory as a variable, which makes it possible to get the byte

相关标签:
5条回答
  • 2021-02-10 10:22

    This is an implementation detail, but...

    Not all addresses are stored in memory. The processor also has registers, which can be used to store addresses. There are only a handful of registers which can be used this way, maybe 16 or 32, compared to the billions of bytes you can store in memory.

    Variables in registers

    Some variables will get stored in registers. If you need to quickly add up some numbers, for example, the compiler might use, e.g., %eax (which is a register on x86) to accumulate the result. If optimizations are enabled, it is quite common for variables to exist only in registers. Of course, only a few variables can be in registers at any given time, so most variables will need to get written to memory at some point.

    If a variable is saved to memory because there aren't enough registers, it is called "spilling". Compilers work very hard to avoid register spilling.

    int func()
    {
        int x = 3;
        return x;
        // x will probably just be stored in %eax, instead of memory
    }
    

    Variables on the stack

    Commonly, one register points to a special region called the "stack". So a pointer used by a function may be stored on the stack, and the address of that pointer can be calculated by doing pointer arithmetic on the stack pointer. The stack pointer doesn't have an address because it's a register, and registers don't have addresses.

    void func()
    {
        int x = 3; // address could be "stack pointer + 8" or something like that
    }
    

    The compiler chooses the layout of the stack, giving each function a "stack frame" large enough to hold all of that function's variables. If optimization is disabled, variables will usually each get their own slot in the stack frame. With optimization enabled, slots will be reused, shared, or optimized out altogether.

    Variables at fixed addresses

    Another alternative is to store data at a fixed location, e.g., "address 100".

    // global variable... could be stored at a fixed location, such as address 100
    int x = 3;
    
    int get_x()
    {
        return x; // returns the contents of address 100
    }
    

    This is actually not uncommon. Remember, that "address 100" doesn't correspond to RAM, necessarily—it is actually a virtual address referring to part of your program's virtual address space. Virtual memory allows multiple programs to all use "address 100", and that address will correspond to a different chunk of physical memory in each running program.

    Absolute addresses can also be used on systems without virtual memory, or for programs which don't use virtual memory: bootloaders, operating system kernels, and software for embedded systems may use fixed addresses without virtual memory.

    An absolute address is specified by the compiler by putting a "hole" in the machine code, called a relocation.

    int get_x()
    {
        return x; // returns the contents of address ???
                  // Relocation: please put the address of "x" here
    }
    

    The linker then chooses the address for x, and places the address in the machine code for get_x().

    Variables relative to the program counter

    Yet another alternative is to store data at a location relative to the code that's being executed.

    // global variable... could be stored at address 100
    int x = 3;
    
    int get_x()
    {
        // this instruction might appear at address 75
        return x; // returns the contents of this address + 25
    }
    

    Shared libraries almost always use this technique, which allows the shared library to be loaded at whatever address is available in a program's address space. Unlike programs, shared libraries can't pick their address, because another shared library might pick the same address. Programs can also use this technique, and this is called a "position-independent executable". Programs will be position-independent on systems which lack virtual memory, or to provide additional security on systems with virtual memory, since it makes it harder to write shell code.

    Just like with absolute addresses, the compiler will put a "hole" in the machine code and ask the linker to fill it in.

    int get_x()
    {
        return x; // return the contents of here + ???
                  // Relocation: put the relative address of x here
    }
    
    0 讨论(0)
  • 2021-02-10 10:29

    The pointer is just a variable. The only difference between this and, e.g. a long variable is that we know that what is stored in a pointer variable is a memory address instead of an integer.

    Therefore, you can find the address of a pointer variable by the same way as you can find the address of any other variable. If you store this address in some other variable, this one will also have an address, of course.

    You confusion seems to originate from the fact that the pointer (i.e. a variable address) can in its turn be stored. But it does not have to be stored anywhere (you only do it when you for some reason need this address). From the point of view of your program, any variable is more or less a named memory location. So the "pointer to the variable" is a named memory location that contains the value that is supposed to "point" to another memory location, hence the name "pointer".

    0 讨论(0)
  • 2021-02-10 10:31

    A variable that is a pointer is still a variable, and acts like any other variable. The compiler knows where the variable is located and how to access its value. It is just that the value happens to be a memory address, that's all.

    0 讨论(0)
  • 2021-02-10 10:33

    From the compilers perspective, whether u declare a pointer or a general variable is just a memory space.When you declare a variable a certain block of memory is allocated to the variable.

    The variable can be any either a general variable or a pointer. So ultimately we have a variables (even pointers are variables only) and they have a memory location.

    0 讨论(0)
  • 2021-02-10 10:47

    Let's say the value of a pointer (the address of a byte in memory) is stored somewhere in memory

    The address of a byte that you allocated, say like this

    char ch = 'a';
    

    is referenced by the compiler in the symbol table with the right offset. At run time, the instructions generated by the compiler will use this offset for moving it to from the primary memory to a register for some operation on it.

    A pointer, in the sense you're asking, is not stored anywhere, it's just a type when you refer to a variable's address, unless you explicitly create a pointer variable to store it like this

    &ch;             // address of ch not stored anywhere
    char *p = &ch;   // now the address of ch is stored in p
    

    Thus there's no recursion concept here.

    0 讨论(0)
提交回复
热议问题