简体   繁体   中英

std::vector<T*> vs std::vector<T> for 64-bit T

In a 3D geometry engine code I read that:

std::vector<GA_Offset*> seems wrong, GA_Offset is merely a 64-bit integer . std::vector<GA_Offset> would be better.

where GA_Offset aka long int is a, possibly, non-contiguous offset to an element in a geometry structure. GA_Offsets remain constant even if an element prior to it is deleted, but will be invalidated if an element is inserted prior to it, or if the element list is defragmented.

In my short C++ experience I've learned that references and pointers are better than passing values. Now I'm a little confused here.

Why is storing values in a std::vector is better than pointer? What difference 64-bit int makes?

Passing and storing are two different things.

It's true that, when passing arguments, a reference is often desirable.

However, storing pointers and references is something you don't do unless you actually need to. It vastly complicates matters, requiring careful object lifetime management. If you don't need it, you just store values and let move semantics take care of the rest (this is particularly true of vectors because they take ownership of their elements).

Whether std::vector<GA_Offset*> is better than std::vector<GA_Offset> or not in this case completely depends on the application. It may be that the container is deliberately storing "handles" for some operational reason. We can't tell, because it depends on what the vector is supposed to do.

std::vector<T> does make sense if T is a 64-bit integer, as its memory layout is just a cache-friendly contiguous array of T s:

+---------+ 
|T|T|...|T|
+---------+

On the other hand, std::vector<T*> is a more complex data structure, where you store the pointers contiguously; but the items (integers) pointed to are not contiguous in memory:

+--------------+ 
|T* | T*|...|T*|
+--------------+
 |   |       |
 \-> \->     \->

So, vector<T*> is much more inefficient and less cache-friendly than vector<T> for a simple integer T .

I would definitely suggest using vector<T> for a 64-bit integer T . Why would you need the additional level of indirection of T* ?

Moreover, pay attention when storing raw pointers in STL containers. Raw observing pointers are fine; but raw owning pointers are a source of "leaktrocities", and you should consider storing smart owning pointers instead (eg std::vector<std::unique_ptr<T>> ). But, again, this doesn't make much sense for a simple 64-bit integer type.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM