Does each variable in C/C++ point to a constant address in memory?

Viewed 134

I have 3 Questions:

In C/C++, variables basically hold an address that points to a memory location where the value is held.

For example:

int myVar = 5;

Here, myVar contains the address that points to a memory location that contains 5. If I change the variable value:

myVar = 10;

The memory address stays the same, but the value is overwritten.

  1. Is it possible to change what address myVar holds? (I am not referring to pointers *, just normal variables)

How about for object variables:

class Box {. . .}
Box myBox;

In the above example, myBox variable basically holds the address to a location in memory that contains the object.

  1. Can someone change the address myBox references too? (Again, I am not referring to pointers *, just normal variables).

  2. Does a normal variable hold a constant address in memory for the life of the program?

Thank you guys for your time and understanding!

6 Answers

In C/C++, variables basically hold an address that points to a memory location where the value is held.

That is not correct. Variables are objects which have an address which does not change during the variable's lifetime and hold a value.

For C, this is described in section 6.2.4p2 of the C standard:

The lifetime of an object is the portion of program execution during which storage is guaranteed to be reserved for it. An object exists, has a constant address and retains its last-stored value throughout its lifetime.

So the address of a variable cannot be changed as it is constant throughout the lifetime of the variable.

It's also possible that a variable doesn't have an address at all. If declared with the register keyword, it is not allowed to take the address of such a variable. While the specifics are implementation defined, such a variable could reside entirely in a CPU register in which case it has no address.

If a particular variable never has its address taken, the compiler might also optimize away the variable's address and store it in a register.

Regarding your examples:

int myVar = 5;

Here, the variable myVar has some address, i.e. &myVar, and holds the value 5.

myVar = 10;

This changes the value of myVar to 10.

The variable or object instance's name is its identifier, which provides an "abstract" way of accessing stored information within a program.

There is no way to control the memory address of a variable or object at runtime and the variable may not even be stored in memory. For example, the compiler may choose to store local variables in a register rather than memory if they are only accessed briefly and it will optimize the program in some way.

For global or static variables, you may be able to use a linker script to fix its location for the duration of the program. For local variables, they will either be placed into a register or be placed on the stack and assigned a location relative to the stack pointer.

Alternatively, you can declare a pointer, using int * myVar; or Box myBox; and assign it a specific memory location that will be used for storing information. Although, in most cases a pointer assigned this way should be assigned to the address of another variable or object member by a reference & or dynamically using new or malloc.

In short:

  1. At runtime, no. At compile time, possibly, by using linker scripts and features.
  2. No. This would be treated the same as any other variable.
  3. Static and global variables will hold the same address throughout the life of the program. Local variables are placed on the stack and only "live" while the program is executing the block of code in which they are declared.

Memory address of a variable - if address exists - is always the same (and thus can't be changed), i.e., in your example, &myVar is the same within scope. That said, if the function reenters / recurses, then you might have another myVar that has a different address.

Also note, in practice you likely have some virtual memory management under the ABI that's managed by the OS. So, even if the logical address is the same, the physical address might be remapped. A practical use of this is seen in c++-based languages that do garbage collection.

After compiling & linking, named variables ARE addresses. It is not that there is somewhere else something that "holds or contains" addresses.

Consider int a = 5 declared within curly braces. The compiler generates code that refers to bytes that are somewhere on the stack. With the function, references to 'a' are something like SP+n. That is, 5 is stored and accessed relative to the stack pointer at this point in the execution.

In C/C++, variables basically hold an address that points to a memory location where the value is held.

I would say that this is a significantly incorrect statement.

I would say that a variable basically is the address of a memory location where the value is held.

During compilation, the compiler typically constructs a symbol table which is a map of all the program's variables, and their corresponding addresses.

That map is typically modified by the linker which assigns final memory addresses to each variable and other object.

Is it possible to change what address myVar holds?

No, it is not possible to do this. It's not possible because it's not meaningful (or useful): since myVar is an address, there's nothing to change.

This analogy might be useful: Suppose you live at 123 Main Street. You cannot simply call up the post office and say, you don't like this address, you want it to be 250 Main Street instead. Once an address is assigned to a building, that address is generally fixed. It's more or less the same with objects in a conventionally-compiled computer program.

(Why can't you change your address? Because it would be too confusing. Someone else might already have the address. Even if not, people expect the house between 121 Main Street and 125 Main Street to be number 123, they would never expect to find number 250 there.)

myVar contains the address that points to a memory location that contains 5.

No. myVar doesn't store an address. It's simply a name for an object that stores the value 5. That name is used by the compiler during translation to keep track of all the operations on that object, but it's not present in the resulting machine code.

Is it possible to change what address myVar holds? (I am not referring to pointers *, just normal variables)

No, because myVar does not store an address; again, it's just a name for an object in the abstract machine that the compiler works against as it translates the code.

Can someone change the address myBox references too? (Again, I am not referring to pointers *, just normal variables).

Same answer as above.

Does a normal variable hold a constant address in memory for the life of the program?

For the lifetime of the variable:

6.2.4 Storage durations of objects
...
2 The lifetime of an object is the portion of program execution during which storage is guaranteed to be reserved for it. An object exists, has a constant address,33) and retains its last-stored value throughout its lifetime.34) If an object is referred to outside of its lifetime, the behavior is undefined. The value of a pointer becomes indeterminate when the object it points to (or just past) reaches the end of its lifetime.


33) The term ‘‘constant address’’ means that two pointers to the object constructed at possibly different times will compare equal. The address may be different during two different executions of the same program.

34) In the case of a volatile object, the last store need not be explicit in the program.
C 2011 Online Draft
Related