469,644 Members | 1,774 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,644 developers. It's quick & easy.

STL vector crash with custom class

Hey, I've been getting some very strange results with what seems to be very simple code. All I'm doing is trying to use an STL vector of "cSprite"s -- a class I wrote. The problem arises when I try to resize the vector either explicitly through the "resize" method, or implicitly through the "push_back". Everything compiles fine, but the program crashes upon calling of the methods. If I instead make it a vector of "int"s it can resize, but still crashes upon program exit. I've tried to narrow it down as much as possible, but unfortunately, it's still a bit of code. However, for brevity's sake, I'll only include the class definitions and original usage unless someone would like to see the class contents.

I've been trying to figure this out for days now, and my best guess is just that cSprite has a variable memory footprint, or size. While it may have originally with the cSurface member, it's now a pointer, so this is no longer the case.

Thanks so much for your responses--I've been frustrated with this for a while now.

Original usage:

Expand|Select|Wrap|Line Numbers
  1. std::vector<cSprite> vTest(5); // Fine here
  2. vTest.resize(vTest.size() + 1); // Crashes on this line
cSprite class definition:

Expand|Select|Wrap|Line Numbers
  1. class cSprite  
  2.     {
  3.         public:
  4.             cFRect        FRect;
  5.             cFPoint        Inertia;
  6.             cSurface*    Surface;
  7.             int            Timer;
  8.             int            Type;
  9.  
  10.             void        Set(int _Type, float _Left, float _Top, float _Right, float _Bottom, 
  11.                             float _xInertia, float _yInertia, int _Frame, int _NumberOfFrames, 
  12.                             int _TicsPerFrame, bool _Visible, bool _Enabled);
  13.             void        Clear();
  14.             void        Draw();
  15.             void        Move();
  16.             void        Move(float _x, float _y);
  17.             void        Move(cFPoint _cFPoint);
  18.             void        MoveTo(float _x, float _y);
  19.             void        MoveTo(cFPoint _cFPoint);
  20.             void        IncrementFrame();
  21.             void        IncrementFrame(int _Increment);
  22.             void        ResetFrame();
  23.             int            NumberOfFrames();
  24.             int            TicsPerFrame();
  25.             bool        Visible();
  26.             bool        Enabled();
  27.  
  28.             void        setFRect(cFRect _cFRect);
  29.             void        setFRect(float _Left, float _Top, float _Right, float _Bottom);
  30.             void        setFRect(int _Left, int _Top, int _Right, int _Bottom);
  31.             void        setFRect(double _Left, double _Top, double _Right, double _Bottom);
  32.             void        setInertia(cFPoint _cFPoint);
  33.             void        setInertia(float _x, float _y);
  34.             void        setInertia(int _x, int _y);
  35.             void        setInertia(double _x, double _y);
  36.             void        setNumberOfFrames(int _NumberOfFrames);
  37.             void        setTicsPerFrame(int _TicsPerFrame);
  38.             void        Show();
  39.             void        Show(bool _Show);
  40.             void        Hide();
  41.             void        Enable();
  42.             void        Enable(bool _Enable);
  43.             void        Disable();
  44.  
  45.                         cSprite();
  46.                         cSprite(int _Type, float _Left, float _Top, float _Right, float _Bottom, 
  47.                                 float _xInertia, float _yInertia, int _Frame, int _NumberOfFrames, 
  48.                                 int _TicsPerFrame, bool _Visible, bool _Enabled);
  49.                         ~cSprite();
  50.  
  51.         private:
  52.             int            iFrame;
  53.             int            iNumberOfFrames;
  54.             bool        bVisible;
  55.             bool        bEnabled;
  56.             int            iFrameTimer;
  57.             int            iTicsPerFrame;
  58.             cFRect        FrameRect;
  59.     };
cFRect class definition:

Expand|Select|Wrap|Line Numbers
  1. class cFRect  
  2.     {
  3.         public:
  4.             float        Left();
  5.             float        Right();
  6.             float        Top();
  7.             float        Bottom();
  8.             float        Width();
  9.             float        Height();
  10.             void        Move(float _x, float _y);
  11.             void        Move(int _x, int _y);
  12.             void        Move(double _x, double _y);
  13.             void        MoveTo(float _x, float _y);
  14.             void        MoveTo(int _x, int _y);
  15.             void        MoveTo(double _x, double _y);
  16.             void        setFRect(float _Left, float _Top, float _Right, float _Bottom);
  17.             void        setFRect(int _Left, int _Top, int _Right, int _Bottom);
  18.             void        setFRect(double _Left, double _Top, double _Right, double _Bottom);
  19.             RECT        ToRect();
  20.                         cFRect();
  21.                         cFRect(float _Left, float _Top, float _Right, float _Bottom);
  22.                         cFRect(int _Left, int _Top, int _Right, int _Bottom);
  23.                         cFRect(double _Left, double _Top, double _Right, double _Bottom);
  24.                         ~cFRect();
  25.  
  26.         private:
  27.             float iLeft;
  28.             float iRight;
  29.             float iTop;
  30.             float iBottom;
  31.     };
cFPoint class definition:

Expand|Select|Wrap|Line Numbers
  1. class cFPoint  
  2.     {
  3.  
  4.         public:
  5.             float        X();
  6.             float        Y();
  7.             void        setX(float _x);
  8.             void        setX(int _x);
  9.             void        setX(double _x);
  10.             void        setY(float _y);
  11.             void        setY(int _y);
  12.             void        setY(double _y);
  13.             void        setPoint(float _x, float _y);
  14.             void        setPoint(int _x, int _y);
  15.             void        setPoint(double _x, double _y);
  16.             POINTAPI    ToPointAPI();
  17.                         cFPoint();
  18.                         cFPoint(float _x, float _y);
  19.                         cFPoint(int _x, int _y);
  20.                         cFPoint(double _x, double _y);
  21.                         ~cFPoint();
  22.  
  23.         private:
  24.             float x;
  25.             float y;
  26.     };
Apr 20 '07 #1
5 6383
JosAH
11,448 Expert 8TB
What does your default constructor of your cSprite class do?

kind regards,

Jos
Apr 20 '07 #2
My constructors:

Expand|Select|Wrap|Line Numbers
  1. cSprite::cSprite()
  2. {
  3.     Type = 0;
  4.     FRect.setFRect(0, 0, 0, 0);
  5.     Inertia.setPoint(0, 0);
  6.     iFrame = 0;
  7.     iNumberOfFrames = 0;
  8.     iTicsPerFrame = 0;
  9.     bVisible = false;
  10.     bEnabled = false;
  11.     Surface = NULL;
  12. }
  13.  
  14. cSprite::cSprite(int _Type, float _Left, float _Top, float _Right, float _Bottom, 
  15.         float _xInertia, float _yInertia, int _Frame, int _NumberOfFrames, 
  16.         int _TicsPerFrame, bool _Visible, bool _Enabled)
  17. {
  18.     Type = _Type;
  19.     FRect.setFRect(_Left, _Top, _Right, _Bottom);
  20.     Inertia.setPoint(_xInertia, _yInertia);
  21.     iFrame = _Frame;
  22.     iNumberOfFrames = _NumberOfFrames;
  23.     iTicsPerFrame = _TicsPerFrame;
  24.     bVisible = _Visible;
  25.     bEnabled = _Enabled;
  26.     Surface = NULL;
  27. }
Apr 20 '07 #3
weaknessforcats
9,208 Expert Mod 8TB
You have pointers in yourt class:

cSurface* Surface;

Worse, they are public.

Even worse is no copy constructor.

When you resize a vector, a new vector is created of the wsize and the old vector copied into it. These copies involve call your copy coonstructor, which you don't have. So the compile uses its copy constructor which just copies the pointer. Therefore, the Surface pointer in in the copy is a copy of the pointer in the original. When the destructor is called on the original it scroggs your copy. Then when you use your copy, you crash.

STL requires well-bechaved classes:
1) all appropriate constructors
2) copy coinstructor
3) assignment operator

Try to avoid public data members. They expose your implementation and when these data member names are scattered all over your code, you can't easily change your class. The whole point of a class is to not have public data members.
Apr 20 '07 #4
Wow! Thanks a ton! I've been working on this for a while now and I thought it'd take a while to get a straight answer.

As to the public members thing, yes, I know it's bad practice. I just know I'll be the only one touching the data (no-user specific data) and only so with constants, so error-catching and permissions aren't really an issue. Plus, I only made members public when they were either (A) classes, so they could be passed in their original formats more easily, or (B) intentionally flexible members. By that I mean they're use can vary, so I wouldn't like to restrict them.

Nevertheless, I must confess (though I suppose it's fairly obvious anyway) that I am not the most experienced in writing classes. I would hate ask you to write my code for me, but if there are any good resources you might know of to point me in the right direction (with copy constructors and assignment operators), that would be great!

Again, thank you so much, and I'll be sure to modify the class so I no longer need the pointer.
Apr 20 '07 #5
weaknessforcats
9,208 Expert Mod 8TB
As to the public members thing, yes, I know it's bad practice. I just know I'll be the only one touching the data (no-user specific data) and only so with constants, so error-catching and permissions aren't really an issue. Plus, I only made members public when they were either (A) classes, so they could be passed in their original formats more easily, or (B) intentionally flexible members. By that I mean they're use can vary, so I wouldn't like to restrict them.
I can't tell you the number of developers who have told me this and then quit theri job leaving the rest of us to deal with the mess.

Do not use public data members unless you can write down a clear techincally sound arguiment and then get an experioenced developer to buy off on it.

Your concerned about flexibility are addressed by using inheritance and polymorphism. Plus a dose of Design Patterns.
Apr 21 '07 #6

Post your reply

Sign in to post your reply or Sign up for a free account.

Similar topics

7 posts views Thread by Jerry Krinock | last post: by
2 posts views Thread by Stijn Oude Brunink | last post: by
10 posts views Thread by dalbosco | last post: by
2 posts views Thread by laniik | last post: by
8 posts views Thread by He Shiming | last post: by
9 posts views Thread by kathy | last post: by
15 posts views Thread by Trapulo | last post: by
reply views Thread by gheharukoh7 | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.