Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Memory allocation in C++

I am confused about the memory allocation in C++ in terms of the memory areas such as Const data area, Stack, Heap, Freestore, Heap and Global/Static area. I would like to understand the memory allocation pattern in the following snippet. Can anyone help me to understand this. If there any thing more apart from the variable types mentioned in the example to help understand the concept better please alter the example.

class FooBar
{
      int n; //Stored in stack?

      public:

          int pubVar; //stored in stack?

          void foo(int param)  //param stored in stack
          {
                int *pp = new int; //int is allocated on heap.
                n = param;
                static int nStat;  //Stored in static area of memory
                int nLoc;          //stored in stack?
                string str = "mystring"; //stored in stack?
                ..
                if(CONDITION)
                {
                    static int nSIf; //stored in static area of memory
                    int loopvar;     //stored in stack
                    ..
                }
          }
}

int main(int)
{
     Foobar bar;    //bar stored in stack? or a part of it?

     Foobar *pBar;  //pBar is stored in stack

     pBar = new Foobar();  //the object is created in heap?  What part of the object is stored on heap

}

EDIT:
What confuses me is, if pBar = new Foobar(); stores the object on the heap, how come int nLoc; and int pubVar;, that are components of the object stored on stack? Sounds contradictory to me. Shouldn't the lifetime of pubvar and pBar be the same?

like image 628
blitzkriegz Avatar asked Jan 14 '11 01:01

blitzkriegz


3 Answers

"Heap" and "stack" are outmoded, inaccurate and confusing terms relating to storage duration.

Objects with "automatic storage duration" are what silly people call "stack objects". They're the ones that you will define inside a function as "local variables". They go out of scope when their enclosing block ends.

Objects with "dynamic storage duration" are those that you create on the free store with the aid of the keyword new (or, if you're silly, malloc), and then destroy whenever you like with the keyword delete (or, if you're silly, free).

There are also objects with "static storage duration" that are subject to all sorts of bizarre rules of initialisation order and things. We tend not to use them in idiomatic C++ as much as we can help it.

As for the specific variables in your code example, your comments are all accurate, despite the failure in terminology.

Addendum:

The terms "heap" and "stack" are outdated, relating to back when the most popular runtime libraries used these data structures to store objects which were dynamically- and automatically-allocated, respectively (statically-allocated objects fit into neither category, incidentally).

These days that is not always true, and it's certainly not mandated by the C++ standard, which does not care where things are stored. It only cares about how they are created and destroyed, and about how long they live.

like image 103
Lightness Races in Orbit Avatar answered Oct 19 '22 23:10

Lightness Races in Orbit


I've updated your annotations with what I believe is more correct. Note that Tomalak is correct that 'stack' and 'heap' are not specified by the standard, and mechanisms other than a stack might be used to pass parameters to store automatic variables.

However, I still use those terms because they are actually used quite often in compiler implementations, the terms are more or less well-understood (or easy to understand), and I think they still pragmatically illustrate what you're interested in knowing.

class Foobar
{
      int n; //Stored wherever the current object is stored
             //  (might be static memory, stack or heap depending 
             //  on how the object is allocated)

      public:

          int pubVar; //Stored wherever the current object is stored 
                      //  (might be static memory, stack or heap depending 
                      //  on how the object is allocated)

          void foo(int param)  //param stored in stack or register
          {
                int *pp = new int; //int is allocated on heap.
                n = param;
                static int nStat;  //Stored in static area of memory
                int nLoc;          //stored in stack or register
                string str = "mystring"; // `str` is stored in stack, however 
                                         //    the string object may also use heap 
                                         //    to manage its data
                ..
                if(CONDITION)
                {
                    static int nSIf; //stored in static area of memory
                    int loopvar;     //stored in stack or register
                    ..
                }
          }
}

int main(int)
{
     Foobar bar;    //bar stored in stack

     Foobar *pBar;  //pBar is stored in stack

     pBar = new Foobar();  //the object is created in heap.  
                           //   The non-static data members are stored in that
                           //   memory block.

}
like image 42
Michael Burr Avatar answered Oct 19 '22 23:10

Michael Burr


I agree with Tomalak,

C++ does not care where things are stored. It only cares about how they are constructed and destroyed, and about how long they live.

How it happens, is implementation defined, the compiler might optimize in such a way, that you won't have anything stored on the "stack" when you expect it. The way allocation on the heap happens is defined by the implementation of new/malloc or some third party function (new might call malloc).

What most likely will happen in your example, is this:

Foobar bar; // bar will *most likely* be allocated on the "stack".
Foobar *pBar; // pBar will *most likely* be allocated on the "stack".
pBar = new Foobar(); // pBar will stay as is, and point to the location on the "heap" where your memory is allocated by new.  

A few things that you might be wondering about. A C-style array, like int array[5] is not stored the same way as a int* pointer= new int[5], the second case will most likely use more memory, since it stores not only the memory for the array, but also memory on the "stack" for the pointer.

Static constants such as 5 and "cake" are usually stored in a separate .DATA section of the executable.

The important thing to understand when using C++, most of these things are implementation defined.

like image 35
Endiannes Avatar answered Oct 19 '22 23:10

Endiannes