![]() |
|
![]() |
|
|
Thread Tools | Display Modes |
|
|
#1 |
|
Hobbyist Programmer
|
Dynamic memory - variables
I think this is a common question lots of beginners might ask, but i searched the forums and found no previous threads.
My Questions: What are the differnece between variables and dynamic memory? 'cause whenever I ask google, it tales me that dynamic memory is in a "heap" or something like that. I would also like to know what are the advantages of having dynamic memory over variables or vice versa. Thank You ![]()
__________________
From the bottom of the stone steps... ...i'm calling still. |
|
|
|
|
|
#2 |
|
SEXY SHOELESS GOD OF WAR!
![]() Join Date: Jun 2005
Location: Wet west coast of Canada
Posts: 1,183
Rep Power: 5
![]() |
There are three general types of data storage.
First is on the stack. In arbitrary terms, think of a stack of paper. It's a last-in, first-out (LIFO) data structure. The piece of paper you last added to the stack will be the first one you will remove. The common terminology is 'pushing' to put an item of data on the stack, and 'popping' to remove it. Stacks are used extensively when there is any nesting of function calls going on. For example, say you have functions foo() and bar(). You call foo() from within main(), so the CPU pushes the value of the current code location (the instruction pointer; it points at the next instruction to execute) onto the stack, and then it changes the current code location to the start of foo(). Then foo() calls bar(), and the same thing happens. When bar() returns, the CPU pops the value off the top of the stack into IP, and the CPU resumes execution of the code at the point right after the call to bar(). Control likewise returns to main() when foo() is done. Stacks are also used to allocate 'automatic' variables. By adjusting the stack pointer that refers to the current 'top of stack', you can allocate space for storing variables. Here's a diagram to help you visualize it: numbers in brackets are the hexadecimal meory locations of those stack positions relative to some defined starting point [1C] <- top of stack (next push goes here) [18] <- third local variable [14] <- second local variable [10] <- first local variable (old top of stack) [0C] <- value of calling code's execution point [08] <- first argument to this function [04] <- second argument to this function [00] <- third argument to this function Stack space is usually limited when compared to other types of storage, too. If you have many nested function calls, or plan to allocate lots of auto variables, you should set the stack size to a larger value (it'll be in compiler options somewhere). If your program crashes, and you get a 'stack overflow' message, it's a good guess you need a bigger stack. You should also note that local variables will have whatever values were last in those memory locations. This is why you must initialize local variables before you use them; if you do not, they will contain garbage. Also, stack space does not consume space in your program's executable file, as the stack is set up when your program begins execution. A stack variable can exist multiple times, with each being a different variable. For example, if foo() has an auto variable called x, and foo() calls itself, you have two completely separate copies of x on the stack. This is why when you pass parameters by value, the callee cannot change the values inside the caller. The next type of storage is that allocated from the data segment (or one of them, if you have multiple data segments). This is initialized storage (your compiler will initialize it to some default value, usually 0, unless you specify otherwise), and the values are actually stored as part of the executable file. In other words, the more such data you have, the bigger your program's data segment will be (but you save space in code since there is no need to store the instructions to do the initialization). Unlike stack variables, each of these variables occurs only once. You can make local variables be allocated from the data segment rather than the stack using the static keyword; in this case, they will maintain their values from one call to the next (for example, having a function keep track of how many times it was called by incremting such a variable). This storage allocated from the data segment is often referred to as static storage. It is not to be confused with whether or not a variable is global; it is entirely possible to have a variable declared outside of all functions that has limited scope (by default, its scope is the current source file). The next type of storage is off the heap. When your program begins execution, the operating system gives it a chunk of memory in which it 'lives'. This is referred to as its address space or process space. It can freely make use of this memory, and this is where things like new and malloc() come in. These grab a chunk of memory from the heap, and return a pointer to the beginning of the chunk. The pointer itself, however, must exist in already-allocated space (which may be stack, static, or heap-based). It is sometimes possible (depends on the OS and compiler in use) to expand the program's address space, or request allocations of memory outside it, which then get 'mapped into' the program's address space. This usually happens when there is not enough memory in the heap to meet a request for an allocation, but it might happen in other situations too. Still, memory allocated in this way follows the normal rules for heap storage, in that you get a pointer to it, and use that pointer to access it. There is also another kind of heap, which is a data structure based on a binary tree. This has absolutely nothing to do with heap storage except the name. I mention it so you don't get confused if you run across stuff talking about this sort of heap. Anyways, there are some oversimplifications in this, as I'm sure some of the gurus will point out. However, I was trying to be less technical so you could understand better. If you keep at programming, you'll ahve plenty of time to learn the gritty details. ![]()
__________________
And once again, Probability proves itself willing to sneak into a back alley and service Drama as would a copper-piece harlot. - Vaarsuvius, Order of the Stick |
|
|
|
|
|
#3 |
|
Professional Programmer
![]() Join Date: Sep 2005
Posts: 419
Rep Power: 4
![]() |
A variable is a named block of memory, and dynamic memory is an unnamed block. However, it can get confusing because you refer to unnamed memory with a variable called a pointer.
![]()
__________________
Even if the voices aren't real, they have some pretty good ideas. |
|
|
|
|
|
#4 |
|
Professional Programmer
Join Date: Sep 2005
Location: serbia & montenegro
Posts: 484
Rep Power: 4
![]() |
Ok I will try to explain but I am not so very good it making explainations...
Let's assume you have a string char line[501]; The lenght of that string ( or array of chars whatever you call it ) is fixed to 500 chars + zero. Let's then assume you want to store each line in a file while reading it. That variable takes 501 bytes in your memory which is much( for the older computers it is! ). A better way would be to declare a pointer to string like this: char *line This way, you use only the amount of memory you need, and you even delete that amount ( free the memory ) when you don't need it anymore. Hope that helps a little, if you have any question feel free to ask! |
|
|
|
|
|
#5 |
|
Hobbyist Programmer
|
Sorry for being late, but thank you for the explanation.
![]()
__________________
From the bottom of the stone steps... ...i'm calling still. |
|
|
|
![]() |
| Bookmarks |
| Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
| Thread Tools | |
| Display Modes | |
|
|