开发者

where are member-vars of a class on the heap stored?

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;
}


开发者_Go百科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);
}


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.


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.


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜