marcob8986
marcob8986

Reputation: 195

handling a 2 dimensional vector c++

I need to set up and access a two dimensional vector of structure in C++. My structure is defined as:

struct nodo{
  int last_prod;
  int last_slot;
  float Z_L;
  float Z_U;
  float g;
  bool fathomed;
};

I defined the vector as:

vector<vector<struct nodo> > n_2;

Now,I need to create several elements of n_2, which will then be vectors again, and then access the single members of them. How can I achieve that? that is the piece of code I have so far:

for(int i=1;i<112;i++){
    n_2.push_back(vector<struct nodo>(111-i));       
    for(int j=1;j<112-i;j++){
      n_2[i][j].last_prod=j;
    }
}

which doesn't work.

Upvotes: 1

Views: 5880

Answers (7)

Andrew Rasmussen
Andrew Rasmussen

Reputation: 15099

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.

Upvotes: 3

Riccardo Tramma
Riccardo Tramma

Reputation: 593

The first thing you must pay attention is the starting index that (in both cycles) must start from 0 instead of 1.

The other thing is that you must push something inside the nested vector in order to address it (with the operator []).

Upvotes: 0

N_A
N_A

Reputation: 19897

You're trying to access items that don't exist yet.

for(int i=1;i<112;i++){
    n_2.push_back(vector<struct nodo>()); <--allocates an empty vector    
    for(int j=1;j<112-i;j++){
      n_2[i][j].last_prod=j; <-- accesses indexes in the empty vector
    }
}

Either allocate the items in the vector ahead of time or create then as needed. A better alternative is to use an array instead of a vector since you don't resize the vector anyway. This will have a performance improvement.

Upvotes: 0

Ade YU
Ade YU

Reputation: 2362

for(int i=1;i<112;i++){
    n_2.push_back(vector<struct nodo>(111-i)); 
    // Here you only have n_2[0] ... n_2[i-1] ( the last pushed is n_2[i-1] )
    // So n_2[i] will be out of range
    // And for n_2[i-1], you only have n_2[i-1][0] ... n_2[i-1][110-i]
    // So be careful of the j's value    
    for(int j=1;j<112-i;j++){
      n_2[i][j].last_prod=j;
    }
}

Upvotes: 0

Boris Strandjev
Boris Strandjev

Reputation: 46953

I would recommend you to use resizes, for me at least it looks neater:

n_2.resize(112);
for(int i = 1; i < 112; i++){
    n_2[i].resize(112- i);  
    for(int j = 1; j < 112 - i; j++){
      n_2[i][j].last_prod = j;
    }
}

Upvotes: 0

John Humphreys
John Humphreys

Reputation: 39294

First of all, this isn't a very good way to do it. I'd actually suggest you use a normal 2-d array by this point if you know the dimensions in advance. Or, to stay "C++", you can wrap the vectors in something and provide a more intelligible interface.

Secondly, you should start your array indices from 0 really if you plan on directly accessing your vectors without an iterator.

But, if you really want to do this, your problem is you need to populate the vector before referencing its element.

So,

n_2.push_back(vector<struct nodo>());
n_2[0].push_back(nodo());

//You can now access n_2[0][0] as there is a single nodo element in there.

You'll need to ensure you've added an element to the nested vector before you access it the position where that element would be. So, your code could be:

for(int i=0;i<112;i++){
    n_2.push_back(vector<struct nodo>());       
    for(int j=0;j<112-i;j++){
      //At n_2[i] which we made above, add another nodo.
      n_2[i].push_back(nodo());
    }
}

Upvotes: 0

Mike Seymour
Mike Seymour

Reputation: 254531

In the outer loop, you're creating an empty vector (UPDATE: after the question changed, it's no longer empty, but still isn't big enough); you need to create it with a large enough size:

n_2.push_back(vector<struct nodo>(112-i));

Upvotes: 0

Related Questions