Jump to content
  • Advertisement
Sign in to follow this  
CJWR

using a 2d vector of ints

This topic is 4832 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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.

Share this post


Link to post
Share on other sites
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;
}




Share this post


Link to post
Share on other sites
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;

Share this post


Link to post
Share on other sites
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());

Share this post


Link to post
Share on other sites
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().

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!