blitzkriegz
blitzkriegz

Reputation: 9576

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?

Upvotes: 6

Views: 3245

Answers (4)

Lightness Races in Orbit
Lightness Races in Orbit

Reputation: 385098

"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.

Upvotes: 10

Fred Nurk
Fred Nurk

Reputation: 14212

Non-static data members are "inside" each instance of that class: whether that is on the stack or heap – or elsewhere – is unknown by just looking at the member in the class definition. It does not make sense to talk about the storage of non-static data members without talking about storage of the instance of the class to which they belong.

struct A {
  int n;  // you cannot say n is always on the stack, or always on the heap, etc.
};

int main() {
  A a;  // a is on the stack, so a.n is also on the stack
  A *p = new A();  // *p, which means the object pointed to by p, is on the heap,
                   // so p->n is also on the heap
                   // p itself is on the stack, just like a
  return 0;
}

A global;  // global is neither on the stack nor on the heap, so neither is global.n

"The stack" is where variables scoped to the lifetime of a single function invocation go; this is also called "automatic storage duration". There are various stack allocation strategies and, notably, each thread has its own stack – though which is "the" stack should be clear from context. There's interesting things happening with split stacks (which allow growing and shrinking), but in that case, it's still one stack split into multiple pieces.

"The heap" is only a misnomer in that "the" refers to the "main" heap, as used by malloc and various forms of new; this is also called "dynamic storage duration".

Global variables, static data members, and function-level statics belong to neither the stack nor heap; also called "static storage duration".

Upvotes: 0

Endiannes
Endiannes

Reputation: 53

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.

Upvotes: 1

Michael Burr
Michael Burr

Reputation: 340168

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.

}

Upvotes: 5

Related Questions