What are the difference between a std::vector
and an std::array
in C++? When should one be preferred over another? What are the pros and cons of each? All my textbook does is list how they are the same.
相关问题
- Sorting 3 numbers without branching [closed]
- How to compile C++ code in GDB?
- Why does const allow implicit conversion of refere
- thread_local variables initialization
- What uses more memory in c++? An 2 ints or 2 funct
相关文章
- Numpy matrix of coordinates
- Class layout in C++: Why are members sometimes ord
- How to mock methods return object with deleted cop
- Which is the best way to multiply a large and spar
- C++ default constructor does not initialize pointe
- Selecting only the first few characters in a strin
- What exactly do pointers store? (C++)
- Converting glm::lookat matrix to quaternion and ba
A vector is a container class while an array is an allocated memory.
std::vector
is a template class that encapsulate a dynamic array1, stored in the heap, that grows and shrinks automatically if elements are added or removed. It provides all the hooks (begin()
,end()
, iterators, etc) that make it work fine with the rest of the STL. It also has several useful methods that let you perform operations that on a normal array would be cumbersome, like e.g. inserting elements in the middle of a vector (it handles all the work of moving the following elements behind the scenes).Since it stores the elements in memory allocated on the heap, it has some overhead in respect to static arrays.
std::array
is a template class that encapsulate a statically-sized array, stored inside the object itself, which means that, if you instantiate the class on the stack, the array itself will be on the stack. Its size has to be known at compile time (it's passed as a template parameter), and it cannot grow or shrink.It's more limited than
std::vector
, but it's often more efficient, especially for small sizes, because in practice it's mostly a lightweight wrapper around a C-style array. However, it's more secure, since the implicit conversion to pointer is disabled, and it provides much of the STL-related functionality ofstd::vector
and of the other containers, so you can use it easily with STL algorithms & co. Anyhow, for the very limitation of fixed size it's much less flexible thanstd::vector
.For an introduction to
std::array
, have a look at this article; for a quick introduction tostd::vector
and to the the operations that are possible on it, you may want to look at its documentation.Actually, I think that in the standard they are described in terms of maximum complexity of the different operations (e.g. random access in constant time, iteration over all the elements in linear time, add and removal of elements at the end in constant amortized time, etc), but AFAIK there's no other method of fulfilling such requirements other than using a dynamic array.As stated by @Lucretiel, the standard actually requires that the elements are stored contiguously, so it is a dynamic array, stored where the associated allocator puts it.One of the advantages that vectors have over arrays is that it is possible to find the current size of a vector using vector_name.size().
As you can imagine, this can be quite useful in a variety of situations, where you can fetch number of elements in the array_list easily.
Using the
std::vector<T>
class:...is just as fast as using built-in arrays, assuming you are doing only the things built-in arrays allow you to do (read and write to existing elements).
...automatically resizes when new elements are inserted.
...allows you to insert new elements at the beginning or in the middle of the vector, automatically "shifting" the rest of the elements "up"( does that make sense?). It allows you to remove elements anywhere in the
std::vector
, too, automatically shifting the rest of the elements down....allows you to perform a range-checked read with the
at()
method (you can always use the indexers[]
if you don't want this check to be performed).There are
twothree main caveats to usingstd::vector<T>
:You don't have reliable access to the underlying pointer, which may be an issue if you are dealing with third-party functions that demand the address of an array.
The
std::vector<bool>
class is silly. It's implemented as a condensed bitfield, not as an array. Avoid it if you want an array ofbool
s!During usage,
std::vector<T>
s are going to be a bit larger than a C++ array with the same number of elements. This is because they need to keep track of a small amount of other information, such as their current size, and because wheneverstd::vector<T>
s resize, they reserve more space then they need. This is to prevent them from having to resize every time a new element is inserted. This behavior can be changed by providing a customallocator
, but I never felt the need to do that!Edit: After reading Zud's reply to the question, I felt I should add this:
The
std::array<T>
class is not the same as a C++ array.std::array<T>
is a very thin wrapper around C++ arrays, with the primary purpose of hiding the pointer from the user of the class (in C++, arrays are implicitly cast as pointers, often to dismaying effect). Thestd::array<T>
class also stores its size (length), which can be very useful.To emphasize a point made by @MatteoItalia, the efficiency difference is where the data is stored. Heap memory (required with
vector
) requires a call to the system to allocate memory and this can be expensive if you are counting cycles. Stack memory (possible forarray
) is virtually "zero-overhead" in terms of time, because the memory is allocated by just adjusting the stack pointer and it is done just once on entry to a function. The stack also avoids memory fragmentation. To be sure,std::array
won't always be on the stack; it depends on where you allocate it, but it will still involve one less memory allocation from the heap compared to vector. If you have adefinitely use a
std::array
over a vector. If any of those requirements is not true, then use astd::vector
.If you are considering using multidimensional arrays, then there is one additional difference between std::array and std::vector. A multidimensional std::array will have the elements packed in memory in all dimensions, just as a c style array is. A multidimensional std::vector will not be packed in all dimensions.
Given the following declarations:
A pointer to the first element in the c-style array (cConc) or the std::array (aConc) can be iterated through the entire array by adding 1 to each preceding element. They are tightly packed.
A pointer to the first element in the vector array (vConc) or the pointer array (ptrConc) can only be iterated through the first 5 (in this case) elements, and then there are 12 bytes (on my system) of overhead for the next vector.
This means that a std::vector> array initialized as a [3][1000] array will be much smaller in memory than one initialized as a [1000][3] array, and both will be larger in memory than a std:array allocated either way.
This also means that you can't simply pass a multidimensional vector (or pointer) array to, say, openGL without accounting for the memory overhead, but you can naively pass a multidimensional std::array to openGL and have it work out.