35

I am trying to understand the difference between the stack and heap memory, and this question on SO as well as this explanation did a pretty good job explaining the basics.

In the second explanation however, I came across an example to which I have a specific question, the example is this:

heap allocation example

It is explained that the object m is allocated on the heap, I am just wondering if this is the full story. According to my understanding, the object itself indeed is allocated on the heap as the new keyword has been used for its instantiation.

However, isn't it that the pointer to object m is on the same time allocated on the stack? Otherwise, how would the object itself, which of course is sitting in the heap be accessed. I feel like for the sake of completeness, this should have been mentioned in this tutorial, leaving it out causes a bit of confusion to me, so I hope someone can clear this up and tell me that I am right with my understanding that this example should have basically two statements that would have to say:

1. a pointer to object m has been allocated on the stack

2. the object m itself (so the data that it carries, as well as access to its methods) has been allocated on the heap

Community
  • 1
  • 1
nburk
  • 22,409
  • 18
  • 87
  • 132
  • 2
    Yes your understanding is right. Pointer is allocated on the stack and the object it is pointing to is allocated on the heap. – Mohit Jain Jun 24 '14 at 07:41
  • A pointer is an object. Where an object is located usually depends on its lifetime; objects with static lifetime are located in global memory, objects with dynamic lifetime on the heap, objects with auto lifetime or temporaries on the stack, exceptions in some other special place, etc., etc. Words like stack or heap are just conventions---simple ways of designating the lifetime, and not some specific location in memory. – James Kanze Jun 24 '14 at 08:18

4 Answers4

37

Your understanding may be correct, but the statements are wrong:

A pointer to object m has been allocated on the stack.

m is the pointer. It is on the stack. Perhaps you meant pointer to a Member object.

The object m itself (the data that it carries, as well as access to its methods) has been allocated on the heap.

Correct would be to say the object pointed by m is created on the heap

In general, any function/method local object and function parameters are created on the stack. Since m is a function local object, it is on the stack, but the object pointed to by m is on the heap.

Toby Speight
  • 27,591
  • 48
  • 66
  • 103
Rakib
  • 7,435
  • 7
  • 29
  • 45
26

"stack" and "heap" are general programming jargon. In particular , no storage is required to be managed internally via a stack or a heap data structure.

C++ has the following storage classes

  • static
  • automatic
  • dynamic
  • thread

Roughly, dynamic corresponds to "heap", and automatic corresponds to "stack".

Moving onto your question: a pointer can be created in any of these four storage classes; and objects being pointed to can also be in any of these storage classes. Some examples:

void func()
{
    int *p = new int;            // automatic pointer to dynamic object
    int q;                       // automatic object
    int *r = &q;                 // automatic pointer to automatic object
    static int *s = p;           // static pointer to dynamic object
    static int *s = r;           // static pointer to automatic object (bad idea)
    thread_local int **t = &s;   // thread pointer to static object 
}

Named variables declared with no specifier are automatic if within a function, or static otherwise.

M.M
  • 138,810
  • 21
  • 208
  • 365
  • 1
    +1 mostly for everything before "Moving onto your question" ;) since the question itself is a truism, these added nuances are more important imho. – underscore_d Apr 11 '16 at 22:35
  • Why is a `static pointer to automatic object` bad? Is it because the automatic object will be deallocated when the function ends but the static pointer will live on? Also, if dynamic variables are stored on the heap and automatic variables are stored on the stack, where are static variables stored? This answer really helped me, thank you. – Jay S. Jul 19 '17 at 19:00
  • 1
    @JayS. Yes, it's bad because the static pointer will be pointing to an object that no longer exists once the function returns the first time. "Where things are stored" is a detail of implementations that is beyond the scope of this answer – M.M Jul 19 '17 at 22:10
5

When you declare a variable in a function, it always goes on the stack. So your variable Member* m is created on the stack. Note that by itself, m is just a pointer; it doesn't point to anything. You can use it to point to an object on either the stack or heap, or to nothing at all.

Declaring a variable in a class or struct is different -- those go where ever the class or struct is instantiated.

To create something on the heap, you use new or std::malloc (or their variants). In your example, you create an object on the heap using new and assign its address to m. Objects on the heap need to be released to avoid memory leaks. If allocated using new, you need to use delete; if allocated using std::malloc, you need to use std::free. The better approach is usually to use a "smart pointer", which is an object that holds a pointer and has a destructor that releases it.

user3553031
  • 5,990
  • 1
  • 20
  • 40
  • Does a variable that is declared static in a function end up on the stack? It can't right, considering that is has static allocation ...? – Abdel Aleem Apr 29 '21 at 12:02
  • 1
    Correct, typical stack-based C++ implementations do not store statics on the stack. Statics get stored in a separate area of memory, along-side globals. So most programs have at least three memory regions for data: the stack, heap, and globals. In practice, there are often more, but you can ignore those for the moment. – user3553031 Jul 02 '21 at 22:08
2

Yes, the pointer is allocated on the stack but the object that pointer points to is allocated on the heap. You're correct.

However, isn't it that the pointer to object m is on the same time allocated on the stack?

I suppose you meant the Member object. The pointer is allocated on the stack and will last there for the entire duration of the function (or its scope). After that, the code might still work:

#include <iostream>
using namespace std;

struct Object {
    int somedata;
};

Object** globalPtrToPtr; // This is into another area called 
                         // "data segment", could be heap or stack

void function() {
    Object* pointerOnTheStack = new Object;
    globalPtrToPtr = &pointerOnTheStack;
    cout << "*globalPtrToPtr = " << *globalPtrToPtr << endl;
} // pointerOnTheStack is NO LONGER valid after the function exits

int main() {
     // This can give an access violation,
     // a different value after the pointer destruction
     // or even the same value as before, randomly - Undefined Behavior
    cout << "*globalPtrToPtr = " << *globalPtrToPtr << endl;
    return 0;
}

http://ideone.com/BwUVgm

The above code stores the address of a pointer residing on the stack (and leaks memory too because it doesn't free Object's allocated memory with delete).

Since after exiting the function the pointer is "destroyed" (i.e. its memory can be used for whatever pleases the program), you can no longer safely access it.

The above program can either: run properly, crash or give you a different result. Accessing freed or deallocated memory is called undefined behavior.

Marco A.
  • 43,032
  • 26
  • 132
  • 246