using a 2d vector of ints

Started by
7 comments, last by Zahlman 18 years, 9 months ago
i'm trying to create a 2d vector of ints to store my games text data (why isn't important). however i can't seem to get it to work right. this is how i'm trying to declare my vector: vector<int[16]> texts; now what i want this to do is create a 2d vector with 16 rows (i can only have up to 16 texts) and an unlimited number of columns. this code compiles and runs, so i think it is working. but how do i access say the first int (0) in the first row (0) etc? thank you for your time.
Charles Reed, CEO of CJWR Software LLC
Advertisement
Personally, I would suggest using a 2d vector this way:
std::vector< std::vector<int> > text

(the space between >'s are important, >> is a seperate character in C / C++)

You cannot cast an array, so you're going to end up with a lot of messy new's and delete's doing it your way.

here's some code at ya.
#include <iostream>#include <stdlib.h>#include <vector>int main(int argc, char *argv[]){  std::vector<std::vector<int> > text;  text.resize(2);//resizes the x     //you should prolly have a loop here, but I'm unrolling the loop   //because I'm lazy  text[0].resize(15);// resizes the y for the first x  text[1].resize(15);// resizes the y for the second x.      text[0][0] = 1;    cout << text[0][0] << std::endl;  system("PAUSE");	  return 0;}




I prefer

int *intarray = new int[width*height];

over the vector method or this method

int **intarray = new int*[height];
for(int i = 0; i < height; ++i)
intarray = new int[width];

Several reasons that it's better.
1) Less code
2) Entire array is in contiguous memory, so it's more cache friendly, faster to traverse
3) Easy to clean up after, simply delete [] intarray; no looping to delete

The biggest plus is #2.

The only minor thing is that since in reality it is a 1d array allocated to hold enough for a 2d array, you will need to index it differently. For this I typically use an inline function or macro.

int Index(int x, int y)
{
return width * y + x;
}

then you just access the index you want with intarray[Index(x,y)] = 10;
Quote:Original post by DrEvil
I prefer

int *intarray = new int[width*height];

over the vector method or this method

I tend to combine your method with vector. No reason to have to manually remember to delete your array.
std::vector<int> intarray(width * height, 0);

However, if your concern is with having 16 arrays, then you don't really have a 2D array in the normal sense, because a row of something sounds like it is an inherently different type than a column of something; it just happens that they're both represented by ints. From that perspective, I'd suggest using a vector of vectors as Binomine also suggested. In fact, to highlight the concept that the outer dimension is different than the inner dimension, I'd consider using a typedef as well.
typedef std::vector<int> t_Text;std::vector<t_Text> Texts(16, t_Text());
"We should have a great fewer disputes in the world if words were taken for what they are, the signs of our ideas only, and not for things themselves." - John Locke
Quote:Original post by DrEvil
1) Less code
Agreed, that structure is much easier to code and does, IMHO, produce cleaner code.
Quote:2) Entire array is in contiguous memory, so it's more cache friendly, faster to traverse
Vectors should be in continguous memory. Of course, depending on the implementation, it may not always be the case.
Quote:3) Easy to clean up after, simply delete [] intarray; no looping to delete

vector.clear();?

Personally, I'd say new / delete is harder to clean up after, because you actually have to remember to do so or else you'll create a memory leak.

4th) He said the x must be unlimited, which means you'll also need to give him a resizing function if he wants to use your code. dynamic resizing comes with vectors using .push_back().
well, how much memory would an int array of text[16][1200] take up?
Charles Reed, CEO of CJWR Software LLC
The biggest + for the vector is the exception safety, if an exception occurs, every object on the stack is destroyed and thus no memory leak can be produced by the vector class, but if you're using a raw pointer there is a memory leak.

And I don't think the code of a dynamic array is clearer than that of a vector.
Quote:Original post by CJWR
well, how much memory would an int array of text[16][1200] take up?


75MB on current PCs. Probably won't fit as a static variable.
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan
If you know the inner dimension is always the same, then don't add the overhead (though it is indeed really as small as it could be for what it does) of std::vector; that type implicitly promises "resizable thingy", and a vector of vectors implicitly promises "possibly non-rectangular storage" - you add a couple extra words for length counts and so on, and then do extra work yourself to make sure they're all the same. Ugh.

In C++, arrays... have a few problems, but you can solve the problem quite easily by wrapping your static array into a struct:

#include <iostream>#include <vector>using namespace std;struct row {   int data[16];  // helper function so that calling code doesn't have to see "data"  int& operator[](size_t index) { return data[index]; }  // This version allows us to index into a const row, should we declare one  const int& operator[](size_t index) const { return data[index]; }  // To keep it recognizable as a POD type, I don't define any ctors/dtors,  // which aren't needed anyway - there's only a chunk of plain data here. This  // allows us to initialize a row as if it were the array.};int main(int argc,char *argv[]) {  vector<row> texts;  row item = {1, 0};  texts.push_back(item);  cout << texts[0][12] << endl;  texts[0][1] = 3;  cout << texts[0][1] << endl;}


However, you might prefer to look up boost::multi_array. It's built to offer resizing (and reshaping) functionality while keeping the array rectangular, while not incurring the overhead of using a vector for each dimension. (for the fully general solution this involves a lot of advanced stuff!)

(And yes, I agree that it sucks to have to do this kind of work yourself to do what arrays should do anyway, especially when there's ultimately zero overhead here once everything gets inlined by the optimizer.)

Quote:Original post by CJWR
well, how much memory would an int array of text[16][1200] take up?


Calculate it yourself: sizeof(int), which is 4 bytes normally, times 16*1200.

This topic is closed to new replies.

Advertisement