Where are pointers in C++ stored, on the stack or in the heap?

47,017

Solution 1

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.

Solution 2

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

Solution 3

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.

Solution 4

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.

Share:
47,017
nburk
Author by

nburk

learning &amp; teaching @ prisma.io https://twitter.com/nikolasburk/status/1093913218676940805

Updated on August 15, 2022

Comments

  • nburk
    nburk almost 2 years

    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