Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Vectors in classes

Credits go to Trezker for helping out!
This thread is locked; no one can reply to it. rss feed Print
Vectors in classes
Kauhiz
Member #4,798
July 2004

So far I've been mostly programming in C and using allegro for my projects. A while back I decided to try OpenLayer and I really like it. So I figured if I'll start using OL, I might as well start writing in C++. So I've been reading up on it, and I came up with a question that I haven found the answer to: can I use a vector as a member in a class?

---
It's Ridge Racer! RIIIIIDGE RAAAAACER!

Trezker
Member #1,739
December 2001
avatar

vector as in std::vector?
Sure.

#include <vector>
class meh
{
  std::vector< float > m_vector;
};

Kauhiz
Member #4,798
July 2004

Cool, thanks! I just thought that there might be some quirks with the vector allocating memory if I put it into a class.

---
It's Ridge Racer! RIIIIIDGE RAAAAACER!

CursedTyrant
Member #7,080
April 2006
avatar

I do that all the time.

---------
Signature.
----
[My Website] | [My YouTube Channel]

TeamTerradactyl
Member #7,733
September 2006
avatar

Kauhiz, actually, I prefer using vectors inside of classes (when array are needed, of course), since they are automatically cleaned up when your object goes out of scope. It makes debugging SEGFAULTs 10x easier :)

Ariesnl
Member #2,902
November 2002
avatar

... As for stuffing complete objects in a vector DONT !!
and maybe you'd better use list.

Make a vector or list of pointers to your objects

using namespace std;

list <myClass *> m_lstItems;

Perhaps one day we will find that the human factor is more complicated than space and time (Jean luc Picard)
Current project: [Star Trek Project ] Join if you want ;-)

X-G
Member #856
December 2000
avatar

Don't listen to that. There's no innate reason why you shouldn't be putting objects in vectors or lists.

--
Since 2008-Jun-18, democracy in Sweden is dead. | 悪霊退散!悪霊退散!怨霊、物の怪、困った時は ドーマン!セーマン!ドーマン!セーマン! 直ぐに呼びましょう陰陽師レッツゴー!

Archon
Member #4,195
January 2004
avatar

Quote:

I just thought that there might be some quirks with the vector allocating memory if I put it into a class.

Just make sure that you also clean up the vector - perhaps in the class's destructor.

Ariesnl
Member #2,902
November 2002
avatar

Quote:

Don't listen to that. There's no innate reason why you shouldn't be putting objects in vectors or lists.

Really ?
how about speed when doing a Z sort ::)

Perhaps one day we will find that the human factor is more complicated than space and time (Jean luc Picard)
Current project: [Star Trek Project ] Join if you want ;-)

Kauhiz
Member #4,798
July 2004

Quote:

Just make sure that you also clean up the vector - perhaps in the class's destructor.

Got it, thanks! :)

---
It's Ridge Racer! RIIIIIDGE RAAAAACER!

Archon
Member #4,195
January 2004
avatar

X-G said:

Don't listen to that. There's no innate reason why you shouldn't be putting objects in vectors or lists.

ariesnl said:

how about speed when doing a Z sort ::)

Well, there wasn't any mention of Z-sorting. And, he said vectors or lists and you provided a example of a list.

HoHo
Member #4,534
April 2004
avatar

Quote:

how about speed when doing a Z sort

What about it?
But how about memory fragmentation and having to manually clean up the pointer vector?

__________
In theory, there is no difference between theory and practice. But, in practice, there is - Jan L.A. van de Snepscheut
MMORPG's...Many Men Online Role Playing Girls - Radagar
"Is Java REALLY slower? Does STL really bloat your exes? Find out with your friendly host, HoHo, and his benchmarking machine!" - Jakub Wasilewski

Ariesnl
Member #2,902
November 2002
avatar

it was an example, pointers in lists ( and vectors) are more efficient.

It's a little more work, but it it's worth it

Quote:

What about it?
But how about memory fragmentation and having to manually clean up the pointer vector?

stuffing Objects in a list or a vector won't help with memory fragmentation.

Perhaps one day we will find that the human factor is more complicated than space and time (Jean luc Picard)
Current project: [Star Trek Project ] Join if you want ;-)

HoHo
Member #4,534
April 2004
avatar

Quote:

stuffing Objects in a list or a vector won't help with memory fragmentation.

Vector of 10000 pointers to objects will roughly have 10001 separate memory fragments (assuming objects themselves don't have pointers). Vector of 10000 objects will be in 1 memory fragment. I see a slight difference in numbers. Of cource with linked list things are rather ugly anyways :)

I don't put objects straight to container only when they are massive (>~100 bytes) and when I have to sort them. When I only have massive objects with no(little) sorting or have to sort small objects I put them straight to the container. There is little point in wasting 4(8) bytes per pointer in most cases :)

Also when I have to sort a container I would never use a list. Vectors are way more effective when needing to sort. Actually there quite a very few cases when lists should be used in place of vectors.

__________
In theory, there is no difference between theory and practice. But, in practice, there is - Jan L.A. van de Snepscheut
MMORPG's...Many Men Online Role Playing Girls - Radagar
"Is Java REALLY slower? Does STL really bloat your exes? Find out with your friendly host, HoHo, and his benchmarking machine!" - Jakub Wasilewski

Kris Asick
Member #1,424
July 2001

I recently (as in, yesterday) tried stuffing my T_PAGE object into a vector. It contains the following:

struct T_PAGE
{
  BITMAP *bitmap, *stencil;
  PALETTE palette;
  char *filename;
};

If I tried to store more than one, for some inexplicable reason, pieces of every allocated BITMAP pointer were getting overwritten.

All I did was switch to storing pointers to T_PAGE objects instead of the objects themselves and my code started working.

--- Kris Asick (Gemini)
--- http://www.pixelships.com

--- Kris Asick (Gemini)
--- http://www.pixelships.com

HoHo
Member #4,534
April 2004
avatar

Without any knowledge of your code I'd say you have a memory leak somewhere that tends to overwrite stuff. By moving to pointers you simply overwrite something else and so far it doesn't show up :)

__________
In theory, there is no difference between theory and practice. But, in practice, there is - Jan L.A. van de Snepscheut
MMORPG's...Many Men Online Role Playing Girls - Radagar
"Is Java REALLY slower? Does STL really bloat your exes? Find out with your friendly host, HoHo, and his benchmarking machine!" - Jakub Wasilewski

Kris Asick
Member #1,424
July 2001

I dunno... the only thing that could be wrong is the allocation of the object, but doing T_PAGE() was the only thing the compiler would accept.

Here's the original code. Using this code, all the data in the first T_PAGE object gets screwed up when I create the second one.

std::vector<T_PAGE> page;

try { page.push_back(T_PAGE()); }
catch (...) { CallErrorHandler(5); }
if (page[0].Make_Bitmap(option.xres,option.yres)) CallErrorHandler(5);
page[0].Set_Palette((PALETTE*)data[Default_Palette].dat);
page[0].accessed_before = 1;
clear_bitmap(page[0].bitmap);

try { page.push_back(T_PAGE()); }
catch (...) { CallErrorHandler(5); }
if (page[1].Make_Bitmap(option.xres,option.yres)) CallErrorHandler(5);
page[1].Set_Palette((PALETTE*)data[Default_Palette].dat);
clear_bitmap(page[1].bitmap);

And here's the new code that works perfectly.

std::vector<T_PAGE*> page;

try { page.push_back(new T_PAGE); }
catch (...) { CallErrorHandler(5); }
if (page[0]->Make_Bitmap(option.xres,option.yres)) CallErrorHandler(5);
page[0]->Set_Palette((PALETTE*)data[Default_Palette].dat);
page[0]->accessed_before = 1;
clear_bitmap(page[0]->bitmap);

try { page.push_back(new T_PAGE); }
catch (...) { CallErrorHandler(5); }
if (page[1]->Make_Bitmap(option.xres,option.yres)) CallErrorHandler(5);
page[1]->Set_Palette((PALETTE*)data[Default_Palette].dat);
clear_bitmap(page[1]->bitmap);

Practically identical.

--- Kris Asick (Gemini)
--- http://www.pixelships.com

--- Kris Asick (Gemini)
--- http://www.pixelships.com

X-G
Member #856
December 2000
avatar

... except there's more code that you're not showing us. What is Make_Bitmap? Set_Palette? What else is hiding in T_PAGE that you're not showing us?

--
Since 2008-Jun-18, democracy in Sweden is dead. | 悪霊退散!悪霊退散!怨霊、物の怪、困った時は ドーマン!セーマン!ドーマン!セーマン! 直ぐに呼びましょう陰陽師レッツゴー!

Kris Asick
Member #1,424
July 2001

Nothing I haven't done a million times before:

1int T_PAGE::Make_Bitmap (int xres, int yres) // Return 1 on failure.
2{
3 destroy_bitmap(bitmap);
4 destroy_bitmap(stencil);
5 
6 if ((bitmap = create_bitmap(xres,yres)) == NULL) return 1;
7 if ((stencil = create_bitmap(xres,yres)) == NULL) return 1;
8
9 return 0;
10}
11 
12void T_PAGE::Set_Palette (PALETTE *pal)
13{
14 memcpy(&palette,pal,sizeof(PALETTE));
15}
16 
17T_PAGE::T_PAGE (void)
18{
19 bitmap = NULL; stencil = NULL; filename = NULL;
20 accessed_before = 0;
21}
22 
23T_PAGE::~T_PAGE (void)
24{
25 destroy_bitmap(bitmap);
26 destroy_bitmap(stencil);
27}

Trust me, this part of the code works perfectly. I spent over half an hour checking it before figuring something must be up with the vectors.

Oh yeah, I renamed "palette" to "pal" at one point. I typed out the class by hand in my first post. ;)

--- Kris Asick (Gemini)
--- http://www.pixelships.com

--- Kris Asick (Gemini)
--- http://www.pixelships.com

X-G
Member #856
December 2000
avatar

T_PAGE::~T_PAGE (void)
{
  destroy_bitmap(bitmap);
  destroy_bitmap(stencil);
}

Whoops! :P What do you think happens when this gets called upon vector resizing? That's right, bitmaps get destroyed and eventually thrashed. You need copy semantics for this little baby.

--
Since 2008-Jun-18, democracy in Sweden is dead. | 悪霊退散!悪霊退散!怨霊、物の怪、困った時は ドーマン!セーマン!ドーマン!セーマン! 直ぐに呼びましょう陰陽師レッツゴー!

tobing
Member #5,213
November 2004
avatar

X-G is right, and this means you need to implement operator= and copy constructor for T_PAGE.

Kris Asick
Member #1,424
July 2001

No one told me that in any of the tutorials I was reading, in any of the help files, even here on the forums. No wonder I made that mistake...

Still, using pointers instead of the objects themselves seems to work, and is probably faster too, so wouldn't that just be simpler than coding in operator= and copy constructors?

--- Kris Asick (Gemini)
--- http://www.pixelships.com

--- Kris Asick (Gemini)
--- http://www.pixelships.com

tobing
Member #5,213
November 2004
avatar

Using pointers is faster. As discussed, using many single new's may fragment memory - especially if these memory chunks are allocated and freed in random order, and frequently. There's no problem if they are all allocated once and then used.

Go to: