Click to See Complete Forum and Search --> : Need help with struct & vector


CrazyLuke
October 6th, 2005, 01:19 PM
Lots of info on structs ... lots of info on vectors ... few websites pay much attention to combining them:

I can't get the declaration correct to use code that creates a struct/vector globally. Why won't this work? ...

In my Globals.h:

struct Blocks {
int x;
int y;
}

extern vector<Blocks*> gBlocks;

In Globals.c:

vector <*Blocks> gBlocks;

I wish to access that in several places, for example:

AddBlock (int x, int y) {
Block *b = new Block;
b->x = x;
b->y = y;
gBlocks.push_back(b);
}

BuildBlocks () {
int x, y;
for (x=1, x<=5, a++) {
y = x*3;
AddBlock (x, y);
}
}

It compiles ... but I get an exit with a corrupt stack (I think). The debugger is showing it choke on the memory allocation for the vector.

However, if I do something like this ...

[No vector setup in Globals like before ... just the struct Block is global.]
AddBlock (int x, int y) {
vector<Block*> gBlocks
Block *b = new Block;
b->x = x;
b->y = y;
gBlocks.push_back(b);
}

BuildBlocks () {
int x, y;
for (x=1, x<=5, a++) {
y = x*3;
AddBlock (x, y);
}
}

What happens is that it will compile and run ... BUT in spite of the multiple calls to AddBlock, I only get a vector with one block in it. Is it the multiple hits on the vector statment in AddBlock that is re-setting the vector? Seems like that is what is happening.

Now, this actually works:

BuildBlocks ();
vector<Block*> gBlocks
int x, y;
for (x=1, x<=5, a++) {
y = x*3;
Block *b = new Block;
b->x = x;
b->y = y;
gBlocks.push_back(b);
}
}

But this is not really what I was going for here. I want to declare the vector/struct globally. In other places in the code, I want to:

(1) Access the vector/struct by using an iterator in a block loop to isolate a single block like 'Block b* = gBlocks[it]'
(2) Make assignments and read a block with 'b->'
(3) Add to the vector with 'Block b* = new Block' ... 'gBlocks.push_back(b)'
(4) Delete individual blocks with gBlocks.erase(it). Delete the whole thing with gBlocks.clear().

Am I setting up the vector globally wrong in the first example? Thanks for any help on this, as I've played around with dozens of changes, but nothing works.

Rigel
October 6th, 2005, 01:36 PM
At first glance here's what I've noticed:


BuildBlocks () {
int x, y;
for (x=1, x<=5, a++) {
y = x*3;
AddBlock (x, y);
}
}


Look at your for loop. When will x ever equal five?
Where is "a" defined? I'm sure you probably meant "x++"

CrazyLuke
October 6th, 2005, 01:40 PM
Yes, of course ... sorry about that ... x++!!! orf!

jlou
October 6th, 2005, 01:40 PM
It looks like you have several typos in your post. You should probably just copy and paste (in code tags) the code that doesn't work. Your first attempt looks correct except for what appear to be typos and the fact that you never delete the structs you add to the vector.

Is there a reason you are adding pointers instead of Blocks instances? Also, if you know how to use a vector with a class, then you know how to use it with a struct. If you only know how to use a vector with POD types, then you can use it the same way with the struct you posted because that struct contains only ints.

Rigel
October 6th, 2005, 01:47 PM
Yes copy and paste your code and use code tags. Not only that but be more direct about your problem and what you are trying to accomplish.

It's kind of confusing when you say "I tried X solution but that didn't work so I tried Y solution and that worked but that's not what I'm looking for."

CrazyLuke
October 6th, 2005, 01:51 PM
This is the problem. Google struct+vectors and you do not get one clear example of how this should be set up. I'm new to C++ from other languages, so I'm not familar enough with the language to even understand some parts of your answer.

If the problem here is that I just need to do some more reading on structs and vectors used together, can you say where an example would be located? What you refer to as 'typos' are really a lack of knowledge on my part and a lack of a clear example on the net. Would something like this be found in a general C++ book like 'Carbon in a Nutshell' or 'C++ in a Nutshell'? A quick run down to Barnes & Noble may put me in touch with the answer ...

The basic question is how do you set-up a struct into a global vector that can be accessed, added to, deleted in other classes? I'm sure its simple, but I think you'd be hard pressed to find a clear example in the first 100 Google hits.

Rigel
October 6th, 2005, 01:57 PM
Using structs with vectors isn't hard but if you are completely new to C++ this will be confusing to you. You should start off with simple C++ concepts before you move onto the next. I'd suggest to get some good books.

Good books on C++:
http://www.codeguru.com/forum/showthread.php?t=231039

jlou
October 6th, 2005, 02:00 PM
There is very little different about using a struct with a vector than using an int with a vector.vector<int> intVec;

AddInt(vector<int>& theVec, int newValue)
{
theVec.push_back(newValue);
}

struct Block
{
int x;
int y;
};

vector<Block> blockVec;

AddBlock(vector<Block>& theVec, int newX, int newY)
{
Block newValue;
newValue.x = newX;
newValue.y = newY;
theVec.push_back(newValue);
}The reason there is no example code is that the example code with a struct is the same as with a class (since structs and classes are the same thing), and it is very similar to the code with built-in datatypes. Try just doing it, and if you have problems, show us the actual examples.

CrazyLuke
October 6th, 2005, 02:02 PM
Ok - I'll head to B&N and grab a couple of volumes.

CrazyLuke
October 6th, 2005, 02:06 PM
jlou ... Thank you ... That was exactly what I was looking for. Let me try that first before I plop down $$. I'm porting some code and everything else is working fine. I don't really want to pay for books to get this straight - but - I will need to do more reading.

CrazyLuke
October 6th, 2005, 03:37 PM
GOT IT!!! GOT IT!!! jlou ... your post was all I needed. For those following this, let me show you the final thing that I was trying to do ... get a global vector (that included a struct) that I can access anywhere in my program. And I hope this will show up in Google searches - something like this would have saved me some major time.

From my Global.h:

#include <string>
#include <vector>
using namespace std;

void InitGlobals();

struct Block {
int x;
int y;
};

extern vector<Block> gBlocks;


From my Global.c:

#include "Globals.hxx"
#include <vector>
using namespace std;

vector<Block> gBlocks;

void InitGlobals() {
}


From my Blocks.h:

#include "Globals.hxx"

void AddBlock(int x, int y);
void BuildBlocks(void);


From my Blocks.c:

#include "Block.hxx"
#include "Globals.hxx"
#include <iostream.h>
using namespace std;

void AddBlock(int x, int y) {
Block b;
b.x = x;
b.y = y;
cout << "Settings: x=" << x << " b.x=" << b.x << " b.y=" << b.y << endl;
gBlocks.push_back(b);
}

void BuildBlocks() {
int x, y;
for (x=0; x<=5; x++) {
y = x*3;
AddBlock (x, y);
}
}


And the main.c:

#include <iostream>
#include "Globals.hxx"
#include "Block.hxx"
#include <vector>

int main() {
int x;
Block b;
InitGlobals();
BuildBlocks();

cout << endl << "The size of gBlocks=" << gBlocks.size() << endl << endl;
for (x=0; x<=gBlocks.size(); x++) {
b = gBlocks.at(x);
cout << "List: block=" << x << " x=" << b.x << " y=" << b.y << endl;
}
return 0;
}


The OUTPUT:

Settings: x=0 b.x=0 b.y=0
Settings: x=1 b.x=1 b.y=3
Settings: x=2 b.x=2 b.y=6
Settings: x=3 b.x=3 b.y=9
Settings: x=4 b.x=4 b.y=12
Settings: x=5 b.x=5 b.y=15

The size of gBlocks=6

List: block=0 x=0 y=0
List: block=1 x=1 y=3
List: block=2 x=2 y=6
List: block=3 x=3 y=9
List: block=4 x=4 y=12
List: block=5 x=5 y=15


See, not so hard when you have a genius like jlou helping you out ... thanks again ... huge help!!!!

CrazyLuke
October 6th, 2005, 03:44 PM
Oh - I made one (well, two) small typo mistakes in all that ...

of course, you don't need a '#include <string>' in the Globals.h ... strings are not used here.

More important ... in the main.c ... where I have:

for (x=0; x<=gBlocks.size(); x++) {

that should be:

for (x=0; x<gBlocks.size(); x++) {

The '=' causes an overrun on the end of the vector.

Paul McKenzie
October 6th, 2005, 03:49 PM
The one issue with your code is this:

#include <iostream.h> // Non-standard header

This should be:

#include <iostream> // standard header

There really is no such standard header as "iostream.h". If you tried to compile your code with the latest version of Visual C++, or if you have an ANSI conformant compiler, you will get errors that "iostream.h" doesn't exist.

The actual header that all ANSI C++ compilers have is <iostream>. Once you include this, then the <iostream> types are in namespace std, similar to vector.

Regards,

Paul McKenzie