1

As a class is instantiated on the heap. Are all member vars then also allocated on the heap, or somewhere else. Is there then any good in allocating member vars explicit on the heap?

struct abc {
std::vector<int> vec;
}


int main() {
abc* ptr = new abc(); //the "class" is on the heap but where is vec?
ptr->vec.push_back(42); //where will the 42 be stored?
return 0;
}

will this make any difference

struct abc {
std::vector<int>* vec_ptr;
abc() { vec_ptr = nev std::vector<int>(); }

int main() {
abc* ptr = new abc();
ptr->vec->push_back(42);
}
Sim
  • 4,199
  • 4
  • 39
  • 77
  • What are you trying to achieve? We might be able to help you better if we know that. – Alok Save Oct 02 '11 at 12:47
  • 2
    This is actually about storage duration. Standard C++ has no notion of stack or heap. – pmr Oct 02 '11 at 13:00
  • Possible duplicate of [When vectors are allocated, do they use memory on the heap or the stack?](https://stackoverflow.com/questions/8036474/when-vectors-are-allocated-do-they-use-memory-on-the-heap-or-the-stack) – underscore_d Oct 20 '17 at 11:11
  • 2
    @underscore_d how is that gonna work? The question was asked a full month before the question this is supposed to be a dup of. – Sim Oct 20 '17 at 14:34
  • I don't think it matters, if the other one provides more and better answers. https://meta.stackoverflow.com/questions/315472/old-question-marked-as-duplicate-of-a-new-question – underscore_d Oct 20 '17 at 14:47

3 Answers3

4

Non-static data members are stored inside the object (class instance) they're part of.

If you create an object as a local with automatic storage duration, its members are inside it. If you allocate an object dynamically, they're inside it. If you allocate an object using some entirely different allocation scheme, its members will still be inside it wherever it is. An object's members are part of that object.

Note that here the vector instance here is inside your structure, but vector itself manages its own dynamic storage for the items you push into it. So, the abc instance is dynamically allocated in the usual free store with its vector member inside it, and 42 is in a separate dynamic allocation managed by the vector instance.

For example, say vector is implemented like this:

template <typename T, typename Allocator = std::allocator<T>>
class vector {
    T *data_ = nullptr;
    size_t capacity_ = 0;
    size_t used_ = 0;
    // ...
};

then capacity_ and used_ are both part of your vector object. The data_ pointer is part of the object as well, but the memory managed by the vector (and pointed at by data_) is not.


A note on terminology:

  • with automatic storage duration was originally on the stack. As Loki points out (and I mentioned myself elsewhere), automatic local storage is often implemented using the call stack, but it's an implementation detail.
  • dynamically was originally on the heap - the same objection applies.
  • When I say usual free store, I just mean whatever resource is managed by ::operator new. There could be anything in there, it's another implementation detail.
Community
  • 1
  • 1
Useless
  • 64,155
  • 6
  • 88
  • 132
  • If possible, just use [valgrind](http://valgrind.org/info/tools.html#memcheck) or a checking malloc [eg](http://www.gnu.org/s/hello/manual/libc/Heap-Consistency-Checking.html) before doing lots of speculative work. – Useless Oct 02 '11 at 12:58
  • 2
    Heap and stack are meaningless concepts when used in C++. They also make it harder to think and reason about C++ objects. Variables have storage duration and are stored in their containing context. This is how it is defined (in the standard) and if you think about it this way it simplifies everything. – Martin York Oct 02 '11 at 16:31
  • @Useless: Suppose I have an object created on heap using new keyword. Then in this object, I create another object of another class without using new keyword. Will this create the second object on stack or heap? – Abhishek Dec 30 '14 at 04:03
  • Ask a question showing the specific example your have in mind. There are too many special cases to reasonably handle in comments. – Useless Dec 30 '14 at 14:53
0

Your question could be simplified. Consider:

int main()
{
  std::vector<int> v;
  v.push_back(42);
}

"Where is 42 stored?"

In this example, v is an automatic variable, so it is stored in the local scope's store (usually the stack). But note that v has a fixed, small size -- it's just the handler object. The actual memory for the contained elements is separately allocated by the vector's internal logic, using the specified allocator (in this case, std::allocator), which in turn takes all its memory from the free store.

All the (non-static) data members of a class form part of that class's data type and consume space -- this is essentially the same as a dumb C struct. However, the magic of most C++ library classes lies in the fact that their data members are only tiny pointers, and all the payload data is allocated separately and managed by the class's internal logic.

So when you make a class with lots of vector members, the class itself still won't be very big. Any instance of that class will be allocated in its entirety wherever and however you want it (automatically, dynamically, statically), but be aware that each member object will request additional, separate memory all by itself to do its work.

Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
0

the newed object is treated as a contiguous allocation. creating a new instance of abc creates an allocation with a minimum size of sizeof(abc).

the system does not allocate members of the class separately when you create via new. to illustrate: new does not call new for each member, sub-member. therefore, the data members are stored in the contiguous allocation created by new, which is a single allocation.

in the case of the vector, the vector internally uses dynamic allocation for its elements -- this is accomplished using a separate allocation. this allocation is made within vector's implementation.

therefore the members do reside on the heap, but they exist as part of the abc instance and that instance uses one allocation, excluding any allocations the data members create.

Is there then any good in allocating member vars explicit on the heap?

yes. there are many reasons you might choose to do this. considering the context of the question: you should favor declaring your members as values until there is a very good reason not to (details here). when you need to declare your member as a heap allocation, always use an appropriate container (e.g. auto pointer, shared pointer) because this will save you tons of effort, time, and complexity.

Community
  • 1
  • 1
justin
  • 104,054
  • 14
  • 179
  • 226