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.
Multidimensional Vectors in C++
If you are able to use C++11, multidimensional arrays and vectors of vectors can be initialized in a similar manner.
int a1[3][3] = { {1, 2, 3}, {4, 5, 6}, {7, 8, 9} };
std::vector<std::vector<int>> a2 = { {1, 2, 3}, {4, 5, 6}, {7, 8, 9} };
However, there are differences that must be understood to access the elements without running into undefined behavior.
For a multidimensional array, memory for the elements of the array is required to be allocated contiguously. For a vector of vector, the memory for the elements is most likely going to be disjoint.
Memory for a1
:
a1[0][0] a1[1][0] a1[2][0]
| | |
v v v
+---+---+---+---+---+---+---+---+---+
| | | | | | | | | |
+---+---+---+---+---+---+---+---+---+
Memory for a2
(most likely):
a2[0][0]
|
v
+---+---+---+
| | | |
+---+---+---+
a2[1][0]
|
v
+---+---+---+
| | | |
+---+---+---+
a2[2][0]
|
v
+---+---+---+
| | | |
+---+---+---+
Also, it is possible to defined a vector of vectors in which the number of columns is not same for each row.
std::vector<std::vector<int>> a2 = { {1, 2, 3}, {4, 5}, {6, 7, 8, 9} };
In a multidimensional array, the number of columns is guaranteed to be same for each row.
Given the above multidimensional array a1
, a1[1][2]
will be a valid element and a1[2][3]
will be an invalid element. In the case of a vector of vectors, using the above line, a2[1][2]
is not a valid element and a2[2][3]
is a valid element.
Initializing a two-dimensional std::vector
Use the std::vector::vector(count, value)
constructor that accepts an initial size and a default value:
std::vector<std::vector<int> > fog(
ROW_COUNT,
std::vector<int>(COLUMN_COUNT)); // Defaults to zero initial value
If a value other than zero, say 4
for example, was required to be the default then:
std::vector<std::vector<int> > fog(
ROW_COUNT,
std::vector<int>(COLUMN_COUNT, 4));
I should also mention uniform initialization was introduced in C++11, which permits the initialization of vector
, and other containers, using {}
:
std::vector<std::vector<int> > fog { { 1, 1, 1 },
{ 2, 2, 2 } };
How to define a vector of two dimensional array?
You shouldn't name a variable like a type. You are shadowing std::array
. You should rename the variable and use std::array
instead of C-arrays:
#include <array>
#include <string>
#include <vector>
using StrArr2D = std::array<std::array<std::string, 16>, 16>;
int main() {
StrArr2D arr;
std::vector<StrArr2D> vec;
vec.push_back(arr);
}
You can keep the variable name array
if you avoid using namespace std;
and use full qualified names.
Can I use std::vector<std::vector<T>> to represent two dimensional arrays in C++?
Of course you may use class std::vector to simulate arrays. For example
#include <iostream>
#include <vector>
int main()
{
size_t n;
size_t m;
std::cout << "Enter the number of rows: ";
std::cin >> n;
std::cout << "Enter the number of columns: ";
std::cin >> m;
std::vector<std::vector<int>> v( n, std::vector<int>( m ) );
return 0;
}
Also consider using of the combination of std::vector with std::array when the number of columns is a compile time constant.
A definition of so-called 3-dimensional array can look as for example
std::vector<std::vector<std::vector<int>>>
v( 2, std::vector<std::vector<int>>( 3, std::vector<int>( 4 ) ) );
A more interesting example
#include <iostream>
#include <vector>
#include <numeric>
int main()
{
size_t n;
size_t m;
std::cout << "Enter the number of rows: ";
std::cin >> n;
std::cout << "Enter the number of columns: ";
std::cin >> m;
std::vector<std::vector<int>> v( n, std::vector<int>( m ) );
for ( size_t i = 0; i < n; i++ )
{
std::iota( v[i].begin(), v[i].end(), i * m );
}
for ( const auto &v1 : v )
{
for ( auto x : v1 ) std::cout << x << ' ';
std::cout << std::endl;
}
return 0;
}
If to enter 3 and 5 correspondingly for n and m then the output will be
0 1 2 3 4
5 6 7 8 9
10 11 12 13 14
handling a 2 dimensional vector c++
A vector is size 0 until you tell it to resize, or unless you initialize it with a specific size. Pass the size of your vector in when you create it:
for(int i=1;i<112;i++){
n_2.push_back(vector<struct nodo>(112-i));
for(int j=1;j<112-i;j++){
n_2[i][j].last_prod=j;
}
}
Also, it looks like you are skipping over the 0th index, which means your first value in your array will be skipped. That is probably undesired.
Finally, if your array is a constant size, consider using std::array rather than std::vector. Note that std::array is a C++11 feature and may not be available depending on your compiler.
If I were writing this code, I'd probably write it like this:
#include <array>
using namespace std;
// allocate an array of 112 <struct nodo> arrays, each of size 112
array<array<struct nodo, 112>, 112> n_2;
for (int i = 0; i < 112; i++)
{
for (int j = 0; j < 112; j++)
{
n_2[i][j].last_prod = j;
}
}
Or alternatively, if I don't have a compiler that supports C++11:
#include <vector>
using namespace std;
// allocate a vector of size 112 of <struct nodo> vectors, each of size 112
vector<vector<struct nodo> > n_2(112, vector<struct nodo>(112));
for (int i = 0; i < 112; i++)
{
for (int j = 0; j < 112; j++)
{
n_2[i][j].last_prod = j;
}
}
Even more ideally, you should use a 1 dimensional vector, and simply treat it as a 2 dimensional vector. This way, you can do a single allocation of memory all at once rather than 112 smaller allocations. This is getting pretty nitpicky but obviously a O(1) solution is better than an O(n) solution which is better than a O(n^2) solution in terms of allocations since allocations are slow.
C++ Two Dimensional std::vector best practices
When you want a square or 2d grid, do something similar to what the compiler does for multidimensional arrays (real ones, not an array of pointers to arrays) and store a single large array which you index correctly.
Example using the Matrix class below:
struct Map {
private:
Matrix<MapCell> cells;
public:
void loadMap() {
Matrix<MapCell> cells (WIDTH, HEIGHT);
for (int i = 0; i < WIDTH; i++) {
for (int j = 0; j < HEIGHT; j++) {
// modify cells[i][j]
}
}
swap(this->cells, cells);
// if there's any problem loading, don't modify this->cells
// Matrix swap guarantees no-throw (because vector swap does)
// which is a common and important aspect of swaps
}
};
Variants of matrix classes abound, and there are many ways to tailor for specific use. Here's an example in less than 100 lines that gets you 80% or more of what you need:
#include <algorithm>
#include <memory>
#include <vector>
template<class T, class A=std::allocator<T> >
struct Matrix {
typedef T value_type;
typedef std::vector<value_type, A> Container;
Matrix() : _b(0) {}
Matrix(int a, int b, value_type const& initial=value_type())
: _b(0)
{
resize(a, b, initial);
}
Matrix(Matrix const& other)
: _data(other._data), _b(other._b)
{}
Matrix& operator=(Matrix copy) {
swap(*this, copy);
return *this;
}
bool empty() const { return _data.empty(); }
void clear() { _data.clear(); _b = 0; }
int dim_a() const { return _b ? _data.size() / _b : 0; }
int dim_b() const { return _b; }
value_type* operator[](int a) {
return &_data[a * _b];
}
value_type const* operator[](int a) const {
return &_data[a * _b];
}
void resize(int a, int b, value_type const& initial=value_type()) {
if (a == 0) {
b = 0;
}
_data.resize(a * b, initial);
_b = b;
}
friend void swap(Matrix& a, Matrix& b) {
using std::swap;
swap(a._data, b._data);
swap(a._b, b._b);
}
template<class Stream>
friend Stream& operator<<(Stream& s, Matrix const& value) {
s << "<Matrix at " << &value << " dimensions "
<< value.dim_a() << 'x' << value.dim_b();
if (!value.empty()) {
bool first = true;
typedef typename Container::const_iterator Iter;
Iter i = value._data.begin(), end = value._data.end();
while (i != end) {
s << (first ? " [[" : "], [");
first = false;
s << *i;
++i;
for (int b = value._b - 1; b; --b) {
s << ", " << *i;
++i;
}
}
s << "]]";
}
s << '>';
return s;
}
private:
Container _data;
int _b;
};
Related Topics
Why Copy Constructor Is Called When Passing Temporary by Const Reference
May Volatile Be in User Defined Types to Help Writing Thread-Safe Code
C++: Nested Template Classes Error "Explicit Specialization in Non-Namespace Scope"
Is Begin() == End() for Any Empty() Vector
Reading "Integer" Size Bytes from a Char* Array
Is Returning a 2-Tuple Less Efficient Than Std::Pair
What Is the Best Solution to Pause and Resume Pthreads
Initialize Std::Array with a Range (Pair of Iterators)
Why Can't I Put a Variable Declaration in the Test Portion of a While Loop
How to Handle or Avoid a Stack Overflow in C++
C/C++: How to Use the Do-While(0); Construct Without Compiler Warnings Like C4127
How to Disable Exceptions in Stl
Eclipse Indexer Can't Resolve Shared_Ptr