Add to Favorites    Make Home Page 3455 Online  
 Language Categories  
 Our Services  

Pointers And Memory - Contents


Local Memory

A D V E R T I S E M E N T

Search Projects & Source Codes:

    Local Memory: The most common variables you use are "local" variables within functions such as the variables num and result in the following function. All of the local variables and parameters taken together are called its "local storage" or just its "locals", such as num and result in the following code...
// Local storage example
int Square(int num) {
int result;
result = num * num;
return result;
}

    The variables are called "local" to capture the idea that their lifetime is tied to the function where they are declared. Whenever the function runs, its local variables are allocated. When the function exits, its locals are deallocated. For the above example, that means that when the Square() function is called, local storage is allocated for num and result. Statements like result = num * num; in the function use the local storage. When the function finally exits, its local storage is deallocated

    Here is a more detailed version of the rules of local storage...

1. When a function is called, memory is allocated for all of its locals. In other words, when the flow of control hits the starting '{' for the function, all of its locals are allocated memory. Parameters such as num and local variables such as result in the above example both count as locals. The only difference between parameters and local variables is that parameters start out with a value copied from the caller while local variables start with random initial values. This article mostly uses simple int variables for its examples, however local allocation works for any type: structs, arrays... these can all be allocated locally.

2. The memory for the locals continues to be allocated so long as the thread of control is within the owning function. Locals continue to exist even if the function temporarily passes off the thread of control by calling another function. The locals exist undisturbed through all of this.

3. Finally, when the function finishes and exits, its locals are deallocated. This makes sense in a way — suppose the locals were somehow to continue to exist — how could the code even refer to them? The names like num and result only make sense within the body of Square() anyway. Once the flow of control leaves that body, there is no way to refer to the locals even if they were allocated. That locals are available ("scoped") only within their owning function is known as "lexical scoping" and pretty much all languages do it that way now.

    Small Locals Example: Here is a simple example of the lifetime of local storage...
void Foo(int a) { // (1) Locals (a, b, i, scores) allocated when Foo
runs
int i;// This array of 100 floats is allocated locally.
float scores[100];// (2) Local storage is used by the computation
for (i=0; i Bar(i + a); // (3) Locals continue to exist undisturbed,
} // even during calls to other functions.
} // (4) The locals are all deallocated when the function exits.

    Large Locals Example: Here is a larger example which shows how the simple rule "the locals are allocated when their function begins running and are deallocated when it exits" can build more complex behavior. You will need a firm grasp of how local allocation works to understand the material in sections 3 and 4 later.

    The drawing shows the sequence of allocations and deallocations which result when the function X() calls the function Y() twice. The points in time T1, T2, etc. are marked in the code and the state of memory at that time is shown in the drawing


void X() {
int a = 1;
int b = 2;
// T1
Y(a);
// T3
Y(b);
// T5
}
void Y(int p) {
int q;
q = p + 2;
// T2 (first time through), T4 (second time through)
}

    Observations About Local Parameters: Local variables are tightly associated with their function — they are used there and nowhere else. Only the X() code can refer to its a and b. Only the Y() code can refer to its p and q. This independence of local storage is the root cause of both its advantages and disadvantages.

    Advantages Of Locals: Locals are great for 90% of a program's memory needs....

  • Convenient: Locals satisfy a convenient need — functions often need some temporary memory which exists only during the function's computation. Local variables conveniently provide this sort of temporary, independent memory.
  • Efficient:
  • Relative to other memory use techniques, locals are very efficient. Allocating and deallocating them is time efficient (fast) and they are space efficient in the way they use and recycle memory
  • Local Copies: Local parameters are basically local copies of the information from the caller. This is also known as "pass by value." Parameters are local variables which are initialized with an assignment (=) operation from the caller. The caller is not "sharing" the parameter value with the callee in the pointer sense— the callee is getting its own copy. This has the advantage that the callee can change its local copy without affecting the caller. (Such as with the "p" parameter in the above example.) This independence is good since it keeps the operation of the caller and callee functions separate which follows the rules of good software engineering — keep separate components as independent as possible.

    Disadvantages Of Locals: There are two disadvantages of Locals

  • Short Lifetime:
  • Their allocation and deallocation schedule (their "lifetime") is very strict. Sometimes a program needs memory which continues to be allocated even after the function which originally allocated it has exited. Local variables will not work since they are deallocated automatically when their owning function exits. This problem will be solved later in Section 4 with "heap" memory.
  • Restricted Communication:
  • Since locals are copies of the caller parameters, they do not provide a means of communication from the callee back to the caller. This is the downside of the "independence" advantage. Also, sometimes making copies of a value is undesirable for other reasons. We will see the solution to this problem below in Section 3 "Reference Parameters".

    Synonyms For "Local": Local variables are also known as "automatic" variables since their allocation and deallocation is done automatically as part of the function call mechanism. Local variables are also sometimes known as "stack" variables because, at a low level, languages almost always implement local variables using a stack structure in memory.

    The Ampersand (&) Bug — TAB: Now that you understand the allocation schedule of locals, you can appreciate one of the more ugly bugs possible in C and C++. What is wrong with the following code where the function Victim() calls the function TAB()? To see the problem, it may be useful to make a drawing to trace the local storage of the two functions...


// TAB -- The Ampersand Bug function
// Returns a pointer to an int
int* TAB() {
int temp;
return(&temp); // return a pointer to the local int
}
void Victim() {
int* ptr;
ptr = TAB();
*ptr = 42; // Runtime error! The pointee was local to TAB
}

    TAB() is actually fine while it is running. The problem happens to its caller after TAB() exits. TAB() returns a pointer to an int, but where is that int allocated? The problem is that the local int, temp, is allocated only while TAB() is running. When TAB() exits, all of its locals are deallocated. So the caller is left with a pointer to a deallocated variable. TAB()'s locals are deallocated when it exits, just as happened to the locals for Y() in the previous example.

    It is incorrect (and useless) for TAB() to return a pointer to memory which is about to be deallocated. We are essentially running into the "lifetime" constraint of local variables. We want the int to exist, but it gets deallocated automatically. Not all uses of & between functions are incorrect — only when used to pass a pointer back to the caller. The correct uses of & are discussed in section 3, and the way to pass a pointer back to the caller is shown in section 4.

   Local Memory Summary: Locals are very convenient for what they do — providing convenient and efficient memory for a function which exists only so long as the function is executing. Locals have two deficiencies which we will address in the following sections — how a function can communicate back to its caller (Section 3), and how a function can allocate separate memory with a less constrained lifetime (section 4).


Back to Table of Contents


A D V E R T I S E M E N T




Google Groups Subscribe to SourceCodesWorld - Techies Talk
Email:

Free eBook - Interview Questions: Get over 1,000 Interview Questions in an eBook for free when you join JobsAssist. Just click on the button below to join JobsAssist and you will immediately receive the Free eBook with thousands of Interview Questions in an ebook when you join.

 Advertisements  

Google Search

Google

is a part of Vyom Network.

Vyom Network : Web Hosting | Dedicated Server | Free SMS, GRE, GMAT, MBA | Online Exams | Freshers Jobs | Software Downloads | Interview Questions | Jobs, Discussions | Placement Papers | Free eBooks | Free eBooks | Free Business Info | Interview Questions | Free Tutorials | Arabic, French, German | IAS Preparation | Jokes, Songs, Fun | Free Classifieds | Free Recipes | Free Downloads | Bangalore Info | Tech Solutions | Project Outsourcing, Web Hosting | GATE Preparation | MBA Preparation | SAP Info | Software Testing | Google Logo Maker | Freshers Jobs

Sitemap | Privacy Policy | Terms and Conditions
Copyright ©2003-2018 SourceCodesWorld.com, All Rights Reserved.
Page URL: /articles/c/pointers-and-memory/localmemory.asp


Download Yahoo Messenger | Placement Papers | Free SMS | C Interview Questions | C++ Interview Questions | Quick2Host Review