开发者

Usage of objects or pointers to objects as class members and memory allocation

开发者 https://www.devze.com 2023-03-04 12:42 出处:网络
A similar question has been asked here: Class members that are objects - Pointers开发者_运维技巧 or not? C++

A similar question has been asked here:

Class members that are objects - Pointers开发者_运维技巧 or not? C++

so I'll keep it brief.

Say I have an object that contains three stl vectors. Is my thinking correct that if they are regular members of the class, the memory of them will be "together" for the whole object? e.g. my memory would look sth like 10 blocks vector A, 5 blocks vector B, and then 15 blocks vector C. Would then once I insert more objects into vector A so that the space runs out the whole structure including vector B and C need to be moved?

Is that then an argument for pointers? Or are vectors internally only a pointer to the allocated memory? Same question would go for lists etc...

Are there any rules of thumb as to the cost of a redirection vs the cost of copying small objects? Maybe sth along the lines of 5 pointer redirection = 1 integer copy?

Thanks


Say I have an object that contains three stl vectors. Is my thinking correct that if they are regular members of the class, the memory of them will be "together" for the whole object? e.g. my memory would look sth like 10 blocks vector A, 5 blocks vector B, and then 15 blocks vector C.

Each vector occupies a fixed size in the containing object, independent of the number of elements currently stored by the vector. It is likely that the value_type of the vector (e.g. vector<int> has value_type int) won't affect the size of the contained vector object itself: only the amount of heap-allocated store the vector needs in order to maintain its storage capacity (so they're likey to be say 8 or 16 or 32 bytes each but all the same, but not 10 "blocks" (whatever that might be), 5 blocks and 15).

Would then once I insert more objects into vector A so that the space runs out the whole structure including vector B and C need to be moved?

Inserting elements into A can only ever cause existing elements in A to be moved (when the capacity is exceeded). B and C can never be affected.

Is that then an argument for pointers? Or are vectors internally only a pointer to the allocated memory?

YES, it's an argument... such a good one that YES, vectors already do use pointers to the contiguous memory where the actual value_type elements are stored.

Same question would go for lists etc...

YES, lists store their value_type elements on the heap too, and the size of the object embedding or derived from list is unaffected by operations on the list.

Are there any rules of thumb as to the cost of a redirection vs the cost of copying small objects? Maybe sth along the lines of 5 pointer redirection = 1 integer copy?enter code here

C++ runs on too many platforms for there to be good rules of thumb for this. Even on say x86 processors, differences in instruction set, # cores, cache sizes, CPU vendor / model / generation etc. can be overwhelming. Indirection is most costly if it results in memory page faults, and that's very dependent on the overall picture of program execution on the machine. If you care, benchmark real computers running the program until you find statistically relevant and stable results.


Collection classes are implemented internally using pointers - you don't have to worry about them running out of space. As for the copying overhead, don't worry about it unless you have proved by profiling your code that it is a problem.


Since std::vector are dynamically sized, they can't possibly stores their elements as members or as a member array. Remember that the size of an object is known at compile-time.

Even then, there is still something to be said about not using pointer members. Consider this type:

struct fat {
    array<double, 30> data;
    array<long, 30> more_data;
    array<char, 30> too_much_data;
};

where array can be std::array, std::tr1::array or boost::array; it's here just used as a stand-in for a large type. You are correct that fat objects will be, well, large. Changing the members to pointers (or dynamic arrays or any kind of moral equivalent) is still premature: first use the objects as-is, and then if it's too big or otherwise problematic you can dynamically allocate them instead of the members:

fat* so_much_stuff = new fat[30]();
// Better:
std::vector<fat> get_rid_of_it_already(30);

Value semantics just make things easier; it's only until it's too much copying or size or whatever (measure first) but not before that you should use (dynamic) containers and smart pointers (that themselves follow value semantics).

EDIT

std::vector is not 'bad' in general (as a member or not), see the discussion with Tony in the comments.

0

精彩评论

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