Arrays vs Vectors: Introductory Similarities and Differences
arrays:
- are a builtin language construct;
- come almost unmodified from C89;
- provide just a contiguous, indexable sequence of elements; no bells and whistles;
- are of fixed size; you can't resize an array in C++ (unless it's an array of POD and it's allocated with
malloc
); - their size must be a compile-time constant unless they are allocated dynamically;
- they take their storage space depending from the scope where you declare them;
- if dynamically allocated, you must explicitly deallocate them;
- if they are dynamically allocated, you just get a pointer, and you can't determine their size; otherwise, you can use
sizeof
(hence the common idiomsizeof(arr)/sizeof(*arr)
, that however fails silently when used inadvertently on a pointer); - automatically decay to a pointers in most situations; in particular, this happens when passing them to a function, which usually requires passing a separate parameter for their size;
- can't be returned from a function; (Unless it is std::array)
- can't be copied/assigned directly;
- dynamical arrays of objects require a default constructor, since all their elements must be constructed first;
std::vector
:
- is a template class;
- is a C++ only construct;
- is implemented as a dynamic array;
- grows and shrinks dynamically;
- automatically manage their memory, which is freed on destruction;
- can be passed to/returned from functions (by value);
- can be copied/assigned (this performs a deep copy of all the stored elements);
- doesn't decay to pointers, but you can explicitly get a pointer to their data (
&vec[0]
is guaranteed to work as expected); - always brings along with the internal dynamic array its size (how many elements are currently stored) and capacity (how many elements can be stored in the currently allocated block);
- the internal dynamic array is not allocated inside the object itself (which just contains a few "bookkeeping" fields), but is allocated dynamically by the allocator specified in the relevant template parameter; the default one gets the memory from the freestore (the so-called heap), independently from how where the actual object is allocated;
- for this reason, they may be less efficient than "regular" arrays for small, short-lived, local arrays;
- when reallocating, the objects are copied (moved, in C++11);
- does not require a default constructor for the objects being stored;
- is better integrated with the rest of the so-called STL (it provides the
begin()
/end()
methods, the usual STLtypedef
s, ...)
Also consider the "modern alternative" to arrays - std::array
; I already described in another answer the difference between std::vector
and std::array
, you may want to have a look at it.
Vectors vs Array in C++
In programming as in life there is no free meal... Keep that in mind all the time. If you want nice and convenient features you have to pay a price.
std::vector
will add some complexity to your code you don't see. Adding items to your std::vector
does more, then just writing a value. It may allocate new memory and copy the old values to it. And several more things you won't really see.
Switching to std::array
won't give you the boost you might looking for. It is a bit simpler then std::vector
. It is the way to got, when you are looking for an supplement of an plain c array. But still, it will add complexity too.
So my advice is and you will find similar once in good books. Try to optimize your code on algorithm base and not on the implementation. There is much more potential in possible flawed algorithms or there may be much better once. The implementation won't give you the ground braking boost.
std::vector versus std::array in C++
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 of std::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 than std::vector
.
For an introduction to std::array
, have a look at this article; for a quick introduction to std::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.
Pointers vs vectors for arrays c++
You can't use the arrb
variant because the size of an array must be a compile-time constant in C++, but you are trying to use a runtime size here.
If your compiler is compiling this, then it is doing so only because it supports these so-called variable-length arrays as a non-standard extension. Other compilers will not support them or have differing degree of support or behavior. These arrays are optionally-supported in C, but even there they are probably not worth the trouble they cause.
There is no way to allocate a runtime-dependent amount of memory on the stack in C++ (except if you misuse recursive function calls to simulate it).
So yes, you should use the vector
approach. But as discussed in the comments under the question, what you are doing is wrong and causes undefined behavior. You need to either reserve
memory and then emplace_back
/push_back
elements into the vector or you need to resize
the vector to the expected size and then you may index it directly. Indexing a vector outside the the range of elements already created in it causes undefined behavior.
Arrays vs Vectors: Introductory Similarities and Differences
arrays:
- are a builtin language construct;
- come almost unmodified from C89;
- provide just a contiguous, indexable sequence of elements; no bells and whistles;
- are of fixed size; you can't resize an array in C++ (unless it's an array of POD and it's allocated with
malloc
); - their size must be a compile-time constant unless they are allocated dynamically;
- they take their storage space depending from the scope where you declare them;
- if dynamically allocated, you must explicitly deallocate them;
- if they are dynamically allocated, you just get a pointer, and you can't determine their size; otherwise, you can use
sizeof
(hence the common idiomsizeof(arr)/sizeof(*arr)
, that however fails silently when used inadvertently on a pointer); - automatically decay to a pointers in most situations; in particular, this happens when passing them to a function, which usually requires passing a separate parameter for their size;
- can't be returned from a function; (Unless it is std::array)
- can't be copied/assigned directly;
- dynamical arrays of objects require a default constructor, since all their elements must be constructed first;
std::vector
:
- is a template class;
- is a C++ only construct;
- is implemented as a dynamic array;
- grows and shrinks dynamically;
- automatically manage their memory, which is freed on destruction;
- can be passed to/returned from functions (by value);
- can be copied/assigned (this performs a deep copy of all the stored elements);
- doesn't decay to pointers, but you can explicitly get a pointer to their data (
&vec[0]
is guaranteed to work as expected); - always brings along with the internal dynamic array its size (how many elements are currently stored) and capacity (how many elements can be stored in the currently allocated block);
- the internal dynamic array is not allocated inside the object itself (which just contains a few "bookkeeping" fields), but is allocated dynamically by the allocator specified in the relevant template parameter; the default one gets the memory from the freestore (the so-called heap), independently from how where the actual object is allocated;
- for this reason, they may be less efficient than "regular" arrays for small, short-lived, local arrays;
- when reallocating, the objects are copied (moved, in C++11);
- does not require a default constructor for the objects being stored;
- is better integrated with the rest of the so-called STL (it provides the
begin()
/end()
methods, the usual STLtypedef
s, ...)
Also consider the "modern alternative" to arrays - std::array
; I already described in another answer the difference between std::vector
and std::array
, you may want to have a look at it.
Confused about vectors
You are getting confused because the mathematical concept of a vector can mean a "collection of data" and that is what you were taught int v[10]
was. The actual name for that in C++ (and most other languages) is an "array" not a vector.
The libraries referred to in C++ Primer have a class called "vector" which is an implementation of an array. They are similar, but not the same.
I hope that clears that up a bit. You are probably confused because you were taught that int v[10]
is a vector, but it is "not really" in C++. It's an array. Use that term to refer to it. If you ever refer to it as a vector, you will confuse others and yourself.
Difference between 2D vector declarations
My point is that both of these can be understood as vector of vectors.
Absolutely not: vector<vector<int>>a(some_size)
is a vector of vectors. vector<int>b[some_size]
is an array of vectors.
Main difference is vector<int>b[some_size]
is fixed sized, vector<vector<int>>a(some_size) is dynamic, meaning you can
push_backother
vector` and generally manipulate its elements (e.g., erase them, insert other elements etc.).
Advantages of 2D vector array
Automatic deallocation
As @NathanOliver mentioned, you never need to call delete
(often a customized recursive deletion) for multi-dimensional vectors, as the objects inside will be released when they fall out of scope automatically. This can significantly reduce the amount of code you need to write and maintain.
Obviously, if your vectors
contain objects that were allocated with new
or malloc
, you'll need to delete them normally. This is where shared_ptr
s come in but that's another topic.
Regarding overhead
While there is a slight overhead for each vector, it is far more in line with the C++ paradigm to use them over traditional C-style arrays. If your vector is of a fixed size, you can also use std::array<T, N>
, and avoid a lot of the overhead that having a dynamically sized container brings.
C++-ness
Consistency in language is important. If you're going to be writing C++ using the standard library, you should stick to that as closely as is possible. I've worked at many places that use random hodge-podge of C and C++ mixed together, and it makes reading and understanding the code a nightmare.
Is it worth to use vector in case of making a map
I'd use std::array
rather than std::vector
.
For fixed size arrays you get the benefits of STL containers with the performance of 'naked' arrays.
http://en.cppreference.com/w/cpp/container/array
c++ vector one dimensional and two dimensional arrays value assignment
The reason this is happening is because of two reasons.
- The vector you are trying to access is empty
- You are trying to put an
int
into a vector that was supposed to holdvector<int>
s.
Fixed code:
#include <vector>
#include <iostream>
int main()
{
std::vector<int> oneDimArray;
oneDimArray.push_back(5);
for (int i = 0; i < oneDimArray.size(); i++)
{
std::cout << oneDimArray[i];
}
std::vector<std::vector<int>> twoDimArray;
twoDimArray.push_back(oneDimArray); //You can put a vector of ints in here
for (int i = 0; i < twoDimArray.size(); i++)
{
for (int j : twoDimArray[i])
{
std::cout << j;
}
}
return 0;
}
twoDimArray[0].push_back(5)
is invalid because the vector had no size yet. After you have pushed back something, or done twoDimArray.resize(
new size here);
, then you can do that (as long as it isn't out of range).
Also, once a vector has size, you can access the elements of the vector inside the vector by going like twoDimArray[0][0] = 1;
. That would give the first value of the first vector inside of the vector to get the value 1.
Related Topics
What Does the ≫= Operator Mean
Does Mingw-W64 Support Std::Thread Out of the Box When Using the Win32 Threading Model
Why Class Data Members Can't Be Initialized by Direct Initialization Syntax
Top-Level Const Doesn't Influence a Function Signature
Opengl Scale Single Pixel Line
In Stl Maps, Is It Better to Use Map::Insert Than []
What Is the 'Override' Keyword in C++ Used For
What's the Difference Between Size_T and Int in C++
How to Initialise Memory With New Operator in C++
Advantages of Using Std::Make_Unique Over New Operator
How to Automatically Convert Strongly Typed Enum into Int
How to Use Reference Parameters in C++
Throw Keyword in Function'S Signature
How to Remove an Item from a Stl Vector With a Certain Value