You are here:

C++/Memory management in C++

Advertisement


Question
Sir,
I have following questions in C++
1.What is Stack and heap ? What is the use (2 separate) of it?
2.When i declare a global object where it is kept? Stack or heap? How compiler knows about that? Only with new operator?


Answer
1.What is Stack and heap ? What is the use (2 separate) of it?
------------------------------------------------------------------------

The stack and heap are two separate memory areas used for data storage in main memory in a C++ program.

Stack storage is automatically managed by the code and is used for data local to a function call - note I say function call not function. Note that C/C++ call this automatic storage. The stack works by allocating a new block of storage for each function call and relinquishing this storage on function return. Processors usually have support for managing stack data - usually in the form of specific registers to point to current stack top (and maybe a base pointer to the whole stack frame for a function call) and instructions to push and pop data on and off of the stack.

The stack is so named because of the data structure it uses - a stack or LIFO (last in first out).

Stacks are allocated on a per thread of execution basis and are fundamental to most if not all implementations of threads, tasks and other types of units of execution.Operating systems often have a separate kernel mode stack they use internally.

Although the operation of the stack has dynamic properties the compiler has enough information to calculate what storage is required by each function call, and so has static properties as well. Hence I suppose the term automatic rather than dynamic to prevent confusion with fully dynamic storage.

A heap on the other hand is an area where the programmer has to manually manage allocation and deallocation of storage by making specific allocation and deallocation requests (new and delete in C++) and is used for dynamic storage (i.e. storage requested at runtime). The memory used by a heap is usually obtained directly from the operating system, although C/C++ runtime libraries may try to improve performance by requesting big blocks from the operating system and dividing them up for small allocations. The heap is sometimes called the free store in C and C++.

Note that heap is also a data structure. However whether a free store is really implemented as a heap structure is an implementation issue.


2.When i declare a global object where it is kept? Stack or heap?
------------------------------------------------------------------------------------

Neither.

Such data is stored in the static storage area. Static storage is fixed for the whole program duration. The compiler and linker have enough information to calculate the required storage requirements at program build time and this is mapped into memory at program load time - often directly from the executable file. Hence static objects exist for the whole duration of the program - although those requiring complex (i.e. dynamic) initialisation will not be initialised until some specific point in the program execution. Simple static initialisation (e.g. initialising a static int to some value such as 123) can be done at build time and this value just copied from the executable file into memory at program startup.

2a/ How compiler knows about that? Only with new operator?
-------------------------------------------------------------------

i) In a function definition static storage is requested using the static keyword. Otherwise an object has automatic (stack) storage. Unlike local automatic objects, local static objects' state survives across function calls but a local static object cannot be accessed outside of the function (or smaller) scope in which it is defined.

ii) Outside of any function definition _any_ object definition defines an object having static storage.

If such a definition is prefixed with the static keyword then it is private to the source file in which it is defined (or more accurately to the translation unit in which it is defined. A translation unit is approximately what is compiled by the compiler proper after preprocessing). Such private static objects are only visible to code following their definition until the end of the file. Such private static objects are said to have internal linkage.

If such a definition is not prefixed with the static keyword then it has external linkage and is visible as a symbol to the linker, and therefore to other source files (translation units). Such objects _must_ obey the one definition rule across the whole program and not just within the source code file (translation unit) in which they are defined. Only _one_ translation unit can define (i.e. cause storage to be reserved for) an external static object. All other uses must use a declaration by using the extern keyword before the type and name of the global object.


So to summarise:

C and C++ have three types of storage:

1/ Static storage for function-local and internal and external global objects that have storage allocated for the whole of the program duration. Complex static objects requiring dynamic initialisation may not be fully initialised (created) until some later point (if at all) in a programs execution - but once fully created they exist until destroyed during program termination.

2/ Automatic storage on the stack. Such objects apply only to objects defined locally to a function. They exist until the function returns or for a shorter time if they have a smaller scope within the function. Automatic storage is the default storage class for local function objects.

Stacks are allocated on a per unit of execution basis.

3/ Dynamic storage on the free store or heap is managed at runtime (i.e. dynamically) via explicit calls or operators - e.g. new and delete. Objects allocated from the free store exist until explicitly released (freed, deleted, deallocated, etc...).

In addition:

4/ The terms static and dynamic when used in the context of C++ programs often mean "at compile / link time" (static) and "at run time" (dynamic).

5/ A function or object (variable) definition reserves storage for that entity. A declaration merely states that such an entity exists. Such entities can only be _defined_ once in a program. However they can be declared to exist as many times as required. A function declaration is sometimes called a function prototype (from C). Most definitions in C and C++ are also declarations. Only global objects with external linkage can have declarations in C and C++, all other such statements are definitions (and declarations).


Examples:
---------

extern int GlobalInt;          // declaration of a static 'global' object defined elsewhere

int GlobalInt = 12;          // definition of a static 'global' object having external linkage

static int PrivateStatic = 10;      // definition of a static 'global' object having internal linkage

void SomeFunction          // function declaration or prototype; function defined elsewhere
( int n
, long & value
);


void SomeFunction          // function definition:
( int n
, long & value          // arguments are stack based having automatic storage
)
{
   if ( 0==n )          // n for this call different from n of other calls
   {
       return;
   }

   static int callDepth(0);        // Define static local variable. Only created once.
         // State (value) of callDepth survives across function calls.
   ++callDepth;
   
   std::cout   << "At call depth: "
         << callDepth
         << '\n'
         ;
   
   long newValue = value * n;      // Define automatic object stored on function call stack frame

   SomeFunction( n-1, newValue );  // Recursive function call, gets a new stack frame

   value = newValue;
  
   --callDepth;
}          // n, value, newValue for this call destroyed here;
         // callDepth static so continues to exist with its current state

int main()
{
   long * pValue = new long;       // Dynamically create a new long object on the free store at
         // runtime and return a pointer to it. Note the created object
         // is default constructed in this case, which for built in types
         // equates to being uninitialised.
   *pValue = 1;
   SomeFunction(10, *pValue);
   std::cout << "Result of SomeFunction(10, 1) is " << *pValue << std::endl;
   
   delete pValue;          // Objects dynamically created exist until explicitly deleted.
         // Note in this case we could probably get away with forgetting
         // to delete the object pointed to by pValue as the next
         // operation is to terminate the program execution and most
         // modern desktop and server operating systems will be able to
         // release all such process resources. However this is not true
         // in the general case even for dynamically allocated objects
         // that should be deleted as here just before program
         // termination. Some resources held by such objects (of user
         // defined types) may not be automatically released on program
         // termination and some execution environments (e.g. embedded
         // environments) may not do clean up for us.
}
         // Static objects notionally destroyed here: after or during
         // return from main but before program termination.
         // This includes PrivateStatic, GlobalInt and callDepth

Hope this is of use and please ask further questions to clarify anything you do not understand as trying to take all this in at once could be a bit overwhelming and I do not know what you do or do not know already. Hopefully this will at least act as a starting point for your enlightenment of this subject and something we can both refer to if you require further help.  

C++

All Answers


Answers by Expert:


Ask Experts

Volunteer


Ralph McArdell

Expertise

I am a software developer with more than 15 years C++ experience and over 25 years experience developing a wide variety of applications for Windows NT/2000/XP, UNIX, Linux and other platforms. I can help with basic to advanced C++, C (although I do not write just-C much if at all these days so maybe ask in the C section about purely C matters), software development and many platform specific and system development problems.

Experience

My career started in the mid 1980s working as a batch process operator for the now defunct Inner London Education Authority, working on Prime mini computers. I then moved into the role of Programmer / Analyst, also on the Primes, then into technical support and finally into the micro computing section, using a variety of 16 and 8 bit machines. Following the demise of the ILEA I worked for a small company, now gone, called Hodos. I worked on a part task train simulator using C and the Intel DVI (Digital Video Interactive) - the hardware based predecessor to Indeo. Other projects included a CGI based train simulator (different goals to the first), and various other projects in C and Visual Basic (er, version 1 that is). When Hodos went into receivership I went freelance and finally managed to start working in C++. I initially had contracts working on train simulators (surprise) and multimedia - I worked on many of the Dorling Kindersley CD-ROM titles and wrote the screensaver games for the Wallace and Gromit Cracking Animator CD. My more recent contracts have been more traditionally IT based, working predominately in C++ on MS Windows NT, 2000. XP, Linux and UN*X. These projects have had wide ranging additional skill sets including system analysis and design, databases and SQL in various guises, C#, client server and remoting, cross porting applications between platforms and various client development processes. I have an interest in the development of the C++ core language and libraries and try to keep up with at least some of the papers on the ISO C++ Standard Committee site at http://www.open-std.org/jtc1/sc22/wg21/.

Education/Credentials

©2016 About.com. All rights reserved.