0

Just want to know where the data members are in the memory, heap or stack.
Here's my code:

#include <iostream>

#define p(s) std::cout << s << std::endl

class Fook
{
public:
    char c = 'c';  //
    Fook() {
        p(c);
    }
};

class IDK
{
public:
    int* arr = new int[1]; //
    IDK() {
        Fook fook3;        //
        arr[0] = 90;
        Fook* fook4 = new Fook(); //
        p(arr[0]);
    }
};

int main(int argc, char const *argv[])
{
    Fook fook1;
    Fook* fook2 = new Fook();
    
    IDK idk1;
    IDK* idk2 = new IDK();

    return 0;
}

compiles and gives the expected output

c
c
c
c
90
c
c
90

in the above code sample the obj *fook2 and *idk2 are allocated on heap mem and fook1 and idk1 are allocated on stack mem.

  1. is fook2->c on the stack mem (the obj is on the heap mem)
  2. is *arr in idk1 on the heap mem (the obj is on the stack mem)
  3. is *arr in idk2 on the heap mem
  4. is *fook4 in ctor of idk1 on the heap mem
  5. is fook3 in ctor of idk2 on the heap mem
  6. is *fook4 in ctor of idk2 on the heap mem

To summarize everything,
Where are the data members of each object created in int main(int argc, char const *argv[]) in the memory(stack or heap)

Someone
  • 126
  • 8
  • 2
    Member variables are stored in the object, so the only question is where your objects are stored – UnholySheep Sep 17 '21 at 17:17
  • 1
    Gnn..., *on the stack* and *on the heap* are implementation details... The standard wordings are *automatic* for anything that reaches its end of life at the end of the block where it was defined and *allocated* for anything that will have to be explicitely destroyed. And stack and heap are just the common implementations of respectively automatic and allocated. – Serge Ballesta Sep 17 '21 at 17:29
  • @SergeBallesta Well put – Pepijn Kramer Sep 17 '21 at 17:56
  • Handy reading: [Why are the terms "automatic" and "dynamic" preferred over the terms "stack" and "heap" in C++ memory management?](https://stackoverflow.com/questions/9181782/why-are-the-terms-automatic-and-dynamic-preferred-over-the-terms-stack-and) – user4581301 Sep 17 '21 at 18:13

2 Answers2

2

First of all: stacks and heaps are not C++ language concepts, but are implementation concepts. The C++ standard talks about automatic and dynamic storage instead. But for simplicity lets just talk about stacks and heaps.

Typically the new operator will put your object on the heap (unless new operator is overloaded). Otherwise your object goes to the stack.

  1. is fook2->c on the stack mem (the obj is on the heap mem)

The c part of a Fook object will be in the same place where the object is. In the fook2 case it is the heap. Note the subtlety. You said fook2->c which is the arrow operator: it actually loads c (unless overloaded). So the result lands to wherever the left side of fook2->c is.

  1. is *arr in idk1 on the heap mem (the obj is on the stack mem)

Again: arr field on an IDK object lives wherever the object lives. In the case of idk1 we have that arr pointer lives on stack. However the thing it is pointing to, i.e. *arr lives on the heap (since new was used). There's a subtlety here as well: * operator actually loads data to wherever the left side is (again: unless overloaded).

  1. is *arr in idk2 on the heap mem

idk2 lives on the heap, and thus arr pointer lives on the heap. Additionally *arr lives on the heap since that's how it was declared via new operator.

  1. is *fook4 in ctor of idk1 on the heap mem

fook4 pointer lives on the stack. The data it is pointing to lives on the heap.

  1. is fook3 in ctor of idk2 on the heap mem

fook3 object lives on the stack. Always. It doesn't matter that the constructor was called during new initialization of the heap object idk2. Constructor is just a function, a bit special, but not really different from other functions. The constructor doesn't even know whether it is called on a heap or stack object, and it doesn't care.

  1. is *fook4 in ctor of idk2 on the heap mem

Similarly to (3) and (4) fook4 pointer lives on the stack, while the data it is pointing to (i.e. *fook4) lives on the heap.

freakish
  • 54,167
  • 9
  • 132
  • 169
1

Basically

  • fook1: entirely on the stack.
  • fook2: entirely in the heap.
  • idk1: the int* member will be on the stack, and the one element array it points to will be in the heap.
  • idk2: the int* will be on the heap and the array it points to will also be on the heap.
jwezorek
  • 8,592
  • 1
  • 29
  • 46
  • This is assuming the system is implemented with stacks and heaps, a fairly safe assumption. But not a guarantee. A suitably skilled wizard could implement automatic and dynamic storage with hamster wheels and an old VHS copy of Robocop. – user4581301 Sep 17 '21 at 18:15
  • point taken but ... idk... i guess my philosophy in answering these kinds of questions is to answer at the level the person seems to be at. this is someone asking about the basics so I give them the basic answer. Much material out there speaks of "the stack" and "the heap" even though it is true that automatic and dynamic storage is the proper terminology. – jwezorek Sep 17 '21 at 18:20
  • 1
    The comment is not aimed at you. It's for those who follow. If I had problems with the answer there'd be a downvote. – user4581301 Sep 17 '21 at 18:23