Functions and a pointer to a vector of vectors...?

Started by
9 comments, last by Nietsnie 19 years, 1 month ago
I have a vectors of vectors of bytes, and want to pass it to a function so the function can change the values in it. The code (simplified):

// The vector of vectors
vector< vector<char> > heightMap;

// The function
void myFunction (char** heights)              // Is this how it should look?
{
   for (int i=0; i < heights.size(); i++) {   // This isn't right. I want the number of first-order vectors...
      for (int x=0; x < heights.size(); x++ { // And the size of the second-order vector...
         heights.push_back(1);             // How do I push_back a value?
      }
   }
}

// Calling the function
myFunction (heightMap);                       // How do I properly call myFunction passing heightMap as the paramater?
So how do I fix that code up? Thanks for the help!
Advertisement
I like pass by reference. (note the '&' in the function definition). You really want to do that anyway (generally) when working with vectors or lists, because just passing in the vector normally will ENTIRELY copy the whole damn thing which can take a long time if the vector/list is long.

void myFunction( vector< vector<char> > & heightMap ){}myFunction( heightMap );
Thanks! That works great, except for one small part. If I try to do something like:

   for (int i=0; i < heights.size(); i++) {      for (int x=0; x < heights.size(); x++ {       heights.push_back(1);                 // <--- Error occurs on this line.   }}


My compiler complains "invalid conversion from `BYTE**' to `char'". How would I fix this?
Show your whole code for this function (forward declaration and actual definition), as well as for calling the function. "BYTE**" or "char**" probably shouldn't show up at all anywhere in your code, relating to this particular object at least. You probably have some variable or parameter somewhere defined as BYTE** and merely forgot to change it.

[edit] [edit]nevermind[/edit] On closer examination, (I didn't notice your "// <--- Error occurs on this line." comment), as opposed to "push_back(1)", I'm guessing you are trying to push_back a variable, or a more complex expression of some sort. Make sure that the variable or expression evaluates to a char. If it's coming from a 2-dimensional array, make sure that you're accessing the actual elements (push_back(array[i][x])), not just the array (push_back(array)). Or maybe you just need to dereference the double-pointer (push_back(**var)). [/edit]
"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
>> See post below <<
Ack, actually something worse is happening now :(

void LoadFile(LPSTR strName, vector< vector<char> > &pHeightMap, int MAP_SIZE){    char temp[1];    FILE *pFile=NULL;    pFile=fopen(strName,"rb");    for (int i=0;i<MAP_SIZE;i++) {        for (int x=0;x<MAP_SIZE;x++) {            fread(temp,1,1,pFile);            pHeightMap.push_back(temp[0]);    // <--- Line that creates error        }    }}

When that is run, Windows generates a program error "prog.exe has generated errors and will be closed by Windows. Try restarting the program." and the program is forced to close. Why is this happening? (I know the line that creates the error just because if I comment it out the program works.) And the file read code is very ugly... reading one byte at a time... is there any way to read multiple bytes with vectors?

Thanks!
Quote:Original post by Nietsnie
Thanks! That works great, except for one small part. If I try to do something like:

   for (int i=0; i < heights.size(); i++) {      for (int x=0; x < heights.size(); x++ {       heights.push_back(1);                 // <--- Error occurs on this line.   }}


My compiler complains "invalid conversion from `BYTE**' to `char'". How would I fix this?


Warning! There is a definite logic error here too. The .size() is evaluated each time through the loop, and .push_back() onto the vector will increment its size. Thus this becomes an infinite loop. I assume you are trying to modify each "column" within each "row" as you look at them; use heights[i][x] = <whatever> instead.

(If this function is to set up the contents of an empty vector of vectors, you will want to use push_back, but you'll have to get the dimensions from somewhere else.)

Also, note that a vector of vectors is not necessarily "rectangular" storage; the "rows" may all be different lengths.
Ack, thanks for catching that.

EDIT: Actually sorry, that doesn't fix it. I put in bad code in my first posts, and the real code (sans logic error) is in my last post. And I can't see any error in it... >.<
If you're passing an empty vector (of vectors of char) into that function, it's going to explode because pHeightMap[i] may not exist.

Do the following instead:
void LoadFile(LPSTR strName, vector< vector<char> > &HeightMap, int MAP_SIZE){    for (int i = 0; i < MAP_SIZE; i++) {        vector<char> v;        HeightMap.push_back(v);        for (int x = 0; x < MAP_SIZE; x++) {            // acquire data            HeightMap[i].push_back(data]);        }    }}

The bold lines at the outer for loop should solve your problem.
For one, your outer vector never gets resized. So when you access pHeightMap, when i is zero, there isn't actually an element 0, and you access a bad pointer. Here's how I'd quickly rewrite it:
void LoadFile(LPSTR strName, vector< vector<char> > &HeightMap, int MAP_SIZE){    char temp[1];    FILE *pFile=NULL;    pFile=fopen(strName,"rb");    HeightMap.resize(MAP_SIZE);    for (int i=0;i<MAP_SIZE;i++) {        HeightMap.resize(MAP_SIZE);        for (int x=0;x<MAP_SIZE;x++) {            fread(temp,1,1,pFile);            HeightMap[x] = temp[0];        }    }}

Or to make it read more than one byte at a time:
void LoadFile(LPSTR strName, vector< vector<char> > &HeightMap, int MAP_SIZE){    char temp[1];    FILE *pFile=NULL;    pFile=fopen(strName,"rb");    HeightMap.resize(MAP_SIZE);    for (int i=0;i<MAP_SIZE;i++) {        HeightMap.resize(MAP_SIZE);        fread(&(HeightMap[0]),sizeof(char),HeightMap.size(),pFile);    }}

Or I'd even consider just using a 1-dimensional vector, and do the 2-dimensional calculations manually, so that it would all be in one single chunk. (Right now you have what amounts to a jagged array, which isn't bad necessarily, but it's nice to be aware of the difference between a jagged array and a rectangular array.)
void LoadFile(LPSTR strName, vector< char > &HeightMap, int MAP_SIZE){    char temp[1];    FILE *pFile=NULL;    pFile=fopen(strName,"rb");    HeightMap.resize(MAP_SIZE*MAP_SIZE);    fread(&(HeightMap[0]),sizeof(char),HeightMap.size(),pFile);}

One last thing, notice I renamed pHeightMap to HeightMap. It's no longer a pointer, and it's somewhat misleading to prepend 'p' onto a variable that isn't; it is a reference, true, but it's still accessed like a normal variable, not a pointer, so it'd probably be better to leave the 'p' out.
"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

This topic is closed to new replies.

Advertisement