Variables can be held in a number of different places, sometimes in more than one place. Most variables are placed in RAM when a program is loaded; sometimes variables which are declared const are instead placed in ROM. Whenever a variable is accessed, if it is not in the processor's cache, a cache miss will result, and the processor will stall while the variable is copied from RAM/ROM into the cache.
If you have any halfway decent optimizing compiler, local variables will often instead be stored in a processor's register file. Variables will move back and forth between RAM, the cache, and the register file as they are read and written, but they will generally always have a copy in RAM/ROM, unless the compiler decides that's not necessary.
I think you are mixing up two concepts. One, how does the C++ language store variables in memory. Two, how does the computer and operating system manage that memory.
In C++, variables can be allocated on the stack, which is memory that is reserved for the program's use and is fixed in size at thread start or in dynamic memory which can be allocated on the fly using new. A compiler can also choose to store the variables on registers in the processor if analysis of the code will allow it. Those variables would never see the system memory.
If a variable ends up in memory, the OS and the processor chip set take over. Both stack based addresses and dynamic addresses are virtual. That means that they may or may not be resident in system memory at any given time. The in memory variable may be stored in the systems memory, paged onto disk or may be resident in a cache on or near the processor. So, it's hard to know where that data is actually living. If a program hasn't been idle for a time or two programs are competing for memory resources, the value can be saved off to disk in the page file and restored when it is the programs turn to run. If the variable is local to some work being done, it could be modified in the processors cache several times before it is finally flushed back to the system memory. The code you wrote would never know this happened. All it knows is that it has an address to operate on and all of the other systems take care of the rest.
The C++ language supports two kinds of memory allocation through the variables in C++ programs:
Static allocation is what happens when you declare a static or global variable. Each static or global variable defines one block of space, of a fixed size. The space is allocated once, when your program is started (part of the exec operation), and is never freed.
Automatic allocation happens when you declare an automatic variable, such as a function argument or a local variable. The space for an automatic variable is allocated when the compound statement containing the declaration is entered, and is freed when that compound statement is exited. The size of the automatic storage can be an expression that varies. In other CPP implementations, it must be a constant.
A third important kind of memory allocation, dynamic allocation, is not supported by C++ variables but is available Library functions.
Dynamic Memory Allocation
Dynamic memory allocation is a technique in which programs determine as they are running where to store some information. You need dynamic allocation when the amount of memory you need, or how long you continue to need it, depends on factors that are not known before the program runs.
For example, you may need a block to store a line read from an input file; since there is no limit to how long a line can be, you must allocate the memory dynamically and make it dynamically larger as you read more of the line.
Or, you may need a block for each record or each definition in the input data; since you can't know in advance how many there will be, you must allocate a new block for each record or definition as you read it.
When you use dynamic allocation, the allocation of a block of memory is an action that the program requests explicitly. You call a function or macro when you want to allocate space, and specify the size with an argument. If you want to free the space, you do so by calling another function or macro. You can do these things whenever you want, as often as you want.
Dynamic allocation is not supported by CPP variables; there is no storage class “dynamic”, and there can never be a CPP variable whose value is stored in dynamically allocated space. The only way to get dynamically allocated memory is via a system call , and the only way to refer to dynamically allocated space is through a pointer. Because it is less convenient, and because the actual process of dynamic allocation requires more computation time, programmers generally use dynamic allocation only when neither static nor automatic allocation will serve.
For example, if you want to allocate dynamically some space to hold a struct foobar, you cannot declare a variable of type struct foobar whose contents are the dynamically allocated space. But you can declare a variable of pointer type struct foobar * and assign it the address of the space. Then you can use the operators ‘*’ and ‘->’ on this pointer variable to refer to the contents of the space:
Variables are usually stored in RAM. This is either on the heap (e.g. all global variables will usually go there) or on the stack (all variables declared within a method/function usually go there). Stack and Heap are both RAM, just different locations. Pointers have different rules. The pointer to something (a memory block, an object, etc.) itself usually follows the rules of above (a pointer declared within a function is stored on the stack), but the data it points to (the memory block itself or the object you created with new) is stored on the heap. You can create pointers pointing to the stack (e.g. "int a = 10; int * b = &a;", b points to a and a is stored on the stack), but memory allocation using malloc or new counts towards heap memory.
What goes into CPU cache is beyond compilers control, the CPU decides itself what to cache and how to long to cache it (depending on factors like "Has this data been recently used?" or "Is it to be expected that the data is used pretty soon again?" and of course the size of the cache has a big influence for how long CPUs will keep data there - the more cache they have, the more data they can cache and the longer they can keep data there before freeing up cache space for new data).
The compiler might only decide if data goes into a CPU register. Usually data is kept there if it's accessed very often in a row (since register access is faster than cache and much faster than RAM). Some operations on some systems can actually only be performed if the data is in a register - however the compiler will decide whether to copy the data back to RAM immediately after performing an operation on it or to keep it there to perform many more operations on it before writing it back to RAM. It will always try to keep the most often accessed data in a register if possible and if it runs out of registers (depending on how many registers your CPU has), it will decide if it's better to write the data back to RAM (and fetch it from there when needed again), or just temporarily swap the data onto stack and later on fetch it back from there (even though stack is RAM as well, usually using the stack is faster since CPUs usually have the top of stack cached anyway, so pushing to and popping from stack might in fact be only writing to cache and reading back from there, the data might never arrive at memory at all). However when code flow jumps from one method/function to another one, usually all registers are written back to memory, as the compiler can hardly say for sure that the called function/method will not access the memory where the register data came from and when not writing the data back, the function might see an old value still present in memory, as the new value is only in a register and has not been written back yet.
Variables in C++ are stored either on the stack or the heap.
stack:
heap:
That being said, both are structures built in RAM.
If your RAM usage is high though windows can swap this out to disk.
When computation is done on variables, the memory will be copied to registers.
Variables can be held in a number of different places, sometimes in more than one place. Most variables are placed in RAM when a program is loaded; sometimes variables which are declared
const
are instead placed in ROM. Whenever a variable is accessed, if it is not in the processor's cache, a cache miss will result, and the processor will stall while the variable is copied from RAM/ROM into the cache.If you have any halfway decent optimizing compiler, local variables will often instead be stored in a processor's register file. Variables will move back and forth between RAM, the cache, and the register file as they are read and written, but they will generally always have a copy in RAM/ROM, unless the compiler decides that's not necessary.
Variables are stored:
auto
-matic function-local variablesnew
ormalloc
, etc. (details of what it means to say "a variable is stored in the heap" in the comments)static
This is all in RAM, of course. Caching is transparent to userspace processes, though it may visibily affect performance.
Compilers may optimize code to store variables in registers. This is highly compiler and code-dependent, but good compilers will do so aggressively.
I think you are mixing up two concepts. One, how does the C++ language store variables in memory. Two, how does the computer and operating system manage that memory.
In C++, variables can be allocated on the stack, which is memory that is reserved for the program's use and is fixed in size at thread start or in dynamic memory which can be allocated on the fly using new. A compiler can also choose to store the variables on registers in the processor if analysis of the code will allow it. Those variables would never see the system memory.
If a variable ends up in memory, the OS and the processor chip set take over. Both stack based addresses and dynamic addresses are virtual. That means that they may or may not be resident in system memory at any given time. The in memory variable may be stored in the systems memory, paged onto disk or may be resident in a cache on or near the processor. So, it's hard to know where that data is actually living. If a program hasn't been idle for a time or two programs are competing for memory resources, the value can be saved off to disk in the page file and restored when it is the programs turn to run. If the variable is local to some work being done, it could be modified in the processors cache several times before it is finally flushed back to the system memory. The code you wrote would never know this happened. All it knows is that it has an address to operate on and all of the other systems take care of the rest.
The C++ language supports two kinds of memory allocation through the variables in C++ programs:
Static allocation is what happens when you declare a static or global variable. Each static or global variable defines one block of space, of a fixed size. The space is allocated once, when your program is started (part of the exec operation), and is never freed. Automatic allocation happens when you declare an automatic variable, such as a function argument or a local variable. The space for an automatic variable is allocated when the compound statement containing the declaration is entered, and is freed when that compound statement is exited. The size of the automatic storage can be an expression that varies. In other CPP implementations, it must be a constant. A third important kind of memory allocation, dynamic allocation, is not supported by C++ variables but is available Library functions. Dynamic Memory Allocation
Dynamic memory allocation is a technique in which programs determine as they are running where to store some information. You need dynamic allocation when the amount of memory you need, or how long you continue to need it, depends on factors that are not known before the program runs.
For example, you may need a block to store a line read from an input file; since there is no limit to how long a line can be, you must allocate the memory dynamically and make it dynamically larger as you read more of the line.
Or, you may need a block for each record or each definition in the input data; since you can't know in advance how many there will be, you must allocate a new block for each record or definition as you read it.
When you use dynamic allocation, the allocation of a block of memory is an action that the program requests explicitly. You call a function or macro when you want to allocate space, and specify the size with an argument. If you want to free the space, you do so by calling another function or macro. You can do these things whenever you want, as often as you want.
Dynamic allocation is not supported by CPP variables; there is no storage class “dynamic”, and there can never be a CPP variable whose value is stored in dynamically allocated space. The only way to get dynamically allocated memory is via a system call , and the only way to refer to dynamically allocated space is through a pointer. Because it is less convenient, and because the actual process of dynamic allocation requires more computation time, programmers generally use dynamic allocation only when neither static nor automatic allocation will serve.
For example, if you want to allocate dynamically some space to hold a struct foobar, you cannot declare a variable of type struct foobar whose contents are the dynamically allocated space. But you can declare a variable of pointer type struct foobar * and assign it the address of the space. Then you can use the operators ‘*’ and ‘->’ on this pointer variable to refer to the contents of the space:
Variables are usually stored in RAM. This is either on the heap (e.g. all global variables will usually go there) or on the stack (all variables declared within a method/function usually go there). Stack and Heap are both RAM, just different locations. Pointers have different rules. The pointer to something (a memory block, an object, etc.) itself usually follows the rules of above (a pointer declared within a function is stored on the stack), but the data it points to (the memory block itself or the object you created with new) is stored on the heap. You can create pointers pointing to the stack (e.g. "int a = 10; int * b = &a;", b points to a and a is stored on the stack), but memory allocation using malloc or new counts towards heap memory.
What goes into CPU cache is beyond compilers control, the CPU decides itself what to cache and how to long to cache it (depending on factors like "Has this data been recently used?" or "Is it to be expected that the data is used pretty soon again?" and of course the size of the cache has a big influence for how long CPUs will keep data there - the more cache they have, the more data they can cache and the longer they can keep data there before freeing up cache space for new data).
The compiler might only decide if data goes into a CPU register. Usually data is kept there if it's accessed very often in a row (since register access is faster than cache and much faster than RAM). Some operations on some systems can actually only be performed if the data is in a register - however the compiler will decide whether to copy the data back to RAM immediately after performing an operation on it or to keep it there to perform many more operations on it before writing it back to RAM. It will always try to keep the most often accessed data in a register if possible and if it runs out of registers (depending on how many registers your CPU has), it will decide if it's better to write the data back to RAM (and fetch it from there when needed again), or just temporarily swap the data onto stack and later on fetch it back from there (even though stack is RAM as well, usually using the stack is faster since CPUs usually have the top of stack cached anyway, so pushing to and popping from stack might in fact be only writing to cache and reading back from there, the data might never arrive at memory at all). However when code flow jumps from one method/function to another one, usually all registers are written back to memory, as the compiler can hardly say for sure that the called function/method will not access the memory where the register data came from and when not writing the data back, the function might see an old value still present in memory, as the new value is only in a register and has not been written back yet.