4

If you have a line of code like

int num = 4;

Does this result in the following tables?

VARIABLE|ADDRESS   ADDRESS|VALUE
num     |0001      0001   |4

If you were to then say

int* num_p = #

Would this result in the following tables?

VARIABLE|ADDRESS   ADDRESS|VALUE
num     |0001      0001   |4
num_p   |0002      0002   |0001

Would then saying

int** num_pp = &num_p;

Result in the following tables?

VARIABLE|ADDRESS   ADDRESS|VALUE
num     |0001      0001   |4
num_p   |0002      0002   |0001
num_pp  |0003      0003   |0002

And so on? If so, would this same logic hold true if the initial variable were not an int but instead a struct?

EDIT: Check the comments on this question for info on what the addresses would actually look like as opposed to this made up 0001, 0002, 0003 scheme.

EDIT 2: This answer to this question points out the fact that variables do not necessarily have to have an address. This answer to an earlier question also goes into this.

NetherGranite
  • 1,940
  • 1
  • 14
  • 42
  • 2
    Roughly: yes. Except your addresses are naturally just nonsense and their offsets will vary with the size of the variables used. You should write a program then go find the linker map file output, to see where your variables ended up. – Lundin Mar 23 '18 at 14:29
  • 1
    Well, not quite. memory on many processors is byte-adressable and 'address' is a byte address. Usually, addresses in blocks are described as starting at 0, not 1, so 'num' wuld be at address '0000' and, since an int var typically takes 4/8 bytes, 'num_p' would start at 0004/0008. – Martin James Mar 23 '18 at 14:32
  • @Lundin Oh, I was not aware you could do that. I will certainly try that. – NetherGranite Mar 23 '18 at 14:41
  • @MartinJames Okay, that makes sense. Thanks for the clarification. – NetherGranite Mar 23 '18 at 14:42
  • 1
    @NetherGranite Well, depending on the compiler and system, map files may or may not be meaningful. On some systems it just shows where the linker dumped the output of your various .o files, which isn't terribly interesting to know. – Lundin Mar 23 '18 at 14:55

3 Answers3

7

Yes, what you illustrate with your tables is roughly correct. Variable names are assigned to addresses at compile time. This is called a "symbol table" and is analogous to the left-hand tables in your question. When the program runs, the variable names no longer appear in the executable and there are only addresses like you have in your tables on the right.

If so, would this same logic hold true if the initial variable were not an int but instead a struct?

Yes, a struct is a value, so assigning an address to a variable and a value to that address works the same way. The difference is that a struct might take more memory than an int depending on its members. This affects what address is available for the next variable.

Note that the addresses assigned will be offsets from some base memory address. When the OS loads the executable, it gives this base address and the executable calculates the absolute memory addresses by adding the offsets to the base address.

If you are interested in learning more about how this works, you can study compilers and operating systems in more detail.

Code-Apprentice
  • 81,660
  • 23
  • 145
  • 268
  • By base memory address you are alluding to memory segment, right? – machine_1 Mar 23 '18 at 17:03
  • @machine_1 Yah, that sounds like what I mean. It has been a while since I have done anything with these concepts, so my terminology isn't precise. I'm also giving a hand wavy answer to give the OP a general, high-level idea of what is going on here. – Code-Apprentice Mar 23 '18 at 18:32
  • The description in your first place only applies to static variables. The address is not known at compile time for local variables of functions. – M.M Jul 24 '18 at 03:19
  • @M.M You are right, the exact physical address of any variable is unknown at compile time. All addresses are calculated as an offset by the compiler. Static variables are given an address relative to the base address allocated to the program and local variables are given an address relative to the beginning of the stack frame. Of course, the compiler may optimize some variables and assign them to a register instead. For the purposes of this question, all of this is too much detail. – Code-Apprentice Jul 24 '18 at 04:04
1

would this same logic hold true if the initial variable were not an int but instead a struct?

A structure is a type (like int, double, char ...) not a variable, so yes, what you described will apply as well.

Tom's
  • 2,448
  • 10
  • 22
1

Another point worth mentioning is that a variable must not necessarily have a memory address.

The compiler may decide to use a register for a variable or the address could be on the stack in which case it is just an offset to the sp (stack pointer). It can even mix it up. A variable along its scope and lifetime could be stored by the compiler in a register, then in another register, then moved in the memory and then loaded and stored again in a register. Or just replace it with a value (const propagation) or optimize it away completely.

bolov
  • 72,283
  • 15
  • 145
  • 224