Array of classes

Started by
12 comments, last by theObserver 20 years, 7 months ago
I have a map struct for my 2d game defined like: typedef struct __MAPTILE{ char *Owner; int Flags; cSprite *Sprite; } MAPTILE; where cSprite it that class to handles the drawing, storage etc of the bitmap. Later on in my main class I have : public: MAPTILE Map[MAPSIZE]; So when I want to create a sprite I do this: Map[1].Sprite = new cSprite; Map[1].Sprite->Create(); The create method just sets all the variables inside cSprite to 0. eg BOOL cSprite::Create() { Graphic = 0; Timer =0; CurrectTimer =0; } Trouble is it doesnt work. The new statement doesnt seem to assign any actual memory to the pointer because when I put a watch on Graphic or Timer, it shows up as not having any memory or value. So when Create is called and tries to init Graphic to 0, the program just crashes. Any idea why it doesnt work? Thanks.
Advertisement
a) You''re using C++. The ''typedef trick'' of declaring structs should ONLY be used when programming in C.

b) You are expressely forbidden to use any name starting with two underscores, as well as names starting with a single underscore and a capital letter. They are reserved for the implementation and as such are off-limits. Forget __MAPTILE.

c) The code you have put in cSprite::Create rightly belongs in the constructor''s initialization list. Try the following for your cSprite constructor :
cSprite::cSprite() : Graphic(0), Timer(0), CurrentTimer(0) {} 


d) Why is cSprite::Create declared as returning a BOOL ?? I see no return statement in your code.

e) With standard-compliant compilers, when new fails to allocate memory, it throws an exception. Older compilers have it return zero - did you check the return value ?



[ Start Here ! | How To Ask Smart Questions | Recommended C++ Books | C++ FAQ Lite | Function Ptrs | CppTips Archive ]
[ Header Files | File Format Docs | LNK2001 | C++ STL Doc | STLPort | Free C++ IDE | Boost C++ Lib | MSVC6 Lib Fixes ]
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan
I replaced the structure with a class but it still doesnt make any differnce.

The code I showed in cSprite:Create was just something I made up on the fly and is not the actual code because it is not really relevant.

If I do this:

cSprite *Temp = NULL;
Temp = new cSprite;

I can see that what Temp points to a valid cSprite class and I can access all the members with Temp->Whatever and everything works fine.But If I do this:

cSprite *Temp = NULL;
Temp = new cSprite;

Map[1].Sprite = Temp;

It doesnt work. The memory location that Map[1].Sprite points to remains unchanged even after I have assigned Temp to it and the program will crash if I try to access and members within cSprite. So the problem is not with the new statement as I thought but with assigning the pointer to Map[1].Sprite .And it doesnt make much sence to me.

[edited by - theObserver on September 1, 2003 5:12:13 PM]
I created some dummy classes and used your code and mine works without issues.... doing this

cSprite *Temp = NULL;
Temp = new cSprite;
Map[1].Sprite = Temp;

Given that cSprite is a class, with some member variables and a create function.

What is map though? In your earlier post you said

"Later on in my main class I have :
public:
MAPTILE Map[MAPSIZE];"

So i assummed that was part of a class, so i stuck it inside a class.

upon doing that i have something like


class map{   public:      MAPTILE Map[1024];};void main(){   map a;   cSprite *Temp = 0;   Temp = new cSprite;   a.Map[1].Sprite = Temp;   // access data here as temp, or a.Map[1].Sprite}


If i misunderstood where your map structure is, and its a global variable let me know

~ Chris
Thanks for taking the time to try and help. I appreciate it. This is the new class I made to replace the Map structure.(I stripped everything but the pointer that handles the actual drawing out)

class cCreature{  private:  protected:  public:    cSprite *Sprite;    Creature(){};    ~Creature(){};};


I am only trying to make a simple one screen no scrolling game so I want every possible tile location stored in an array. If the tile is empty then it points to NULL otherwise it points to a cCreature class containing the tile information. That way I can just index into the array to find what the user clicked on the screen with the mouse.

This is my main class that is executed on startup and contains the map array. Its derived form cWinShell which just does the basic window house cleaning tasks like creating a registering a window class,entering a mesage loop etc. GameInit() is called just before the main message/game loop is entered and is where I am trying to initilise the map array.

class cChaos : public cWinShell{  private:		LPDIRECTDRAWSURFACE7 lpddsMonsters;		LPDIRECTDRAWSURFACE7 lpddsPointer;		LPDIRECTDRAWSURFACE7 lpddsBackground;		cDirectInput Input;		cSprite SpellList[16];		cSprite MousePtr;		BOOL CreateSpells();		protected:	public:		cChaos() {lpdds = NULL; lpddsBackground = NULL;}		~cChaos() {}                cCreature Map[MAPSIZE];                cGraphics2d Graphics;		BOOL GameInit(); 		int GameLoop();		BOOL GameExit();};////////////////////////////////


And this is the section of GameInit() where I try to assign a pointer to a cSprite to map[0].cSprite

BOOL cChaos::GameInit(){//Other init stuff before this    cSprite *Temp = NULL;  Temp = new cSprite;  Map[1].Sprite = Temp;  Map[1].Sprite->Create(&Graphics,lpdds);}


The same problem occurs. Temp points to memory assigned by the New statment.I assign it but the containts of Map[1].Sprite is not changed and the program crashes on the next line.
I used your code again, without problems. Given mine doesnt do the graphic manipulation yours does, but are you sure this is why it crashes?

And is it crashing on the assignment? or when you access the data? Because if the Map variable isnt being assigned you shouldnt be able to call Create on it...unless that is where its crashing.

class cSprite{};class cCreature{   private:   protected:   public:      cSprite *Sprite;      cCreature(){};      ~cCreature(){}};// The graphics stuff is irrelevant for meclass cChaos{   private:      cCreature Map[100];   public:      void GameInit()      {         //Other init stuff before this         cSprite *Temp = 0;         Temp = new cSprite;         Map[1].Sprite = Temp;         if(Map[1].Sprite == Temp)             cout << "Pointers are equal" << endl;//         Map[1].Sprite->Create();      }};int main(int argc, char* argv[]){   cChaos a;   a.GameInit();}


~ Chris
It crashes in cSprite::Create on the very first line which is:

BOOL cSprite::Create(cGraphics2d * GraphicSource,LPDIRECTDRAWSURFACE7 SSurface,int Index,int Timer,int X,int Y)
{
if (!(Graphics = GraphicSource))
return false;

Graphics is a member of cSprite and from tracing though the code, I can see that GraphicSource has the correct value that is passed to it while Graphics doesnt have any value attacted and the program crashes as soon as the line is read. Grrrrrrrrrrrrr!
Well first off i hope thats a typo....

if(! (Graphics == GraphicsSource) )

= is assignment, == is equal to

As for graphics being null, i assume thats the cGraphics2d class inside your window class. Its not a pointer so it has to have SOME value....

~ Chris
Show us how Graphic is declared - OK I think I found it:
cGraphics2d Graphics;

Is that how it's really declared? Because that's not a pointer! You don't need to use new with it.

[edited by - Magmai Kai Holmlor on September 1, 2003 8:20:02 PM]
- The trade-off between price and quality does not exist in Japan. Rather, the idea that high quality brings on cost reduction is widely accepted.-- Tajima & Matsubara
Here is the cSprite class declaration

class cSprite{  private:	RECT Sprites[6];	RECT *Next;	LPDIRECTDRAWSURFACE7 SourceSurface;	int AnimationTimer;	int CurrentTimer;	cGraphics2d *Graphics;  protected:  public:    cSprite() {Graphics = NULL;SourceSurface=NULL;AnimationTimer = 0;Next=NULL;DrawX=-1;DrawY=-1;}    ~cSprite();    BOOL Create(cGraphics2d * GraphicSource,LPDIRECTDRAWSURFACE7 SSurface,int Index=0,int Timer=0,int X=-1,int Y=-1);		BOOL Animate();		BOOL Draw(int ScaleX=1,int ScaleY=1,int X=-1,int Y=-1);		BOOL GetCords(int Index, RECT *Bounds);		int DrawX;		int DrawY;};


And cGraphic

class cGraphics2d{  private:		LPDIRECTDRAW7 lpdd;		LPDIRECTDRAWPALETTE lpddpal;		LPDIRECTDRAWSURFACE7  lpddsprimary;		LPDIRECTDRAWSURFACE7  lpddsback;		LPDIRECTDRAWCLIPPER lpddclipper;	protected:	public:		cGraphics2d();		~cGraphics2d();		BOOL Shutdown();		BOOL Init(int Width,int Height,int BPP,HWND MainWin);		BOOL DDraw_Attach_Clipper(int num_rects,LPRECT clip_list);		LPDIRECTDRAWSURFACE7 NewSurface(LPDIRECTDRAWSURFACE7 Surface,int Width,int Height,int Transparent = -1, int Flags = VIDEOMEMORY);		BOOL SetPalette(LPPALETTEENTRY Palette);		BOOL Clear(int ClearColour);		BOOL Draw(RECT *Dest,RECT *Source, LPDIRECTDRAWSURFACE7 Surface);		BOOL Flip();};


Now I am going to bang my head off a nice hard wall. The desk isnt hard enough for me anymore.

This topic is closed to new replies.

Advertisement