Array with Variable as Index Problem

Hi, I am making a game using OpenGL and SDL on Windows using Visual Studio Express 2008. The problem is not related with either though (hopefully). I have a pointer array of classes that when I try to create a new class within the array using a variable as the index, the program crashes. The variable is a global variable and is declared outside the main. Sorry if you cannot understand from my explanation.

Basically I have the variable declared outside the main:
int unitCurrentID = 0;
Then the array of classes is declared at the start of the main(). MAX_UNITS is a constant that is set to 20 at the beginning of the program.
1
2
3
4
5
6
Unit* units[MAX_UNITS];
for ( int i = 0; i < MAX_UNITS; i++ )
{
     units[i] = NULL;
}
units[unitCurrentID] = new Unit( 320, 240, UT_CIRCLE );

The problem is in the last line when unitCurrentID is used as the index.

I have tested replacing unitCurrentID with 0, and it works. I have put an if statement around the last line to test if unitCurrentID == 0, which it does.

I don't understand why if unitCurrentID is 0 and doesn't work, but replacing it with 0 works.

I can post my full source code, but it is quite long and I have already isolated it down to these parts, but I will post if need be.

Any help is appreciated.

EDIT:

Unit Class:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
class Unit
{
private:
	double x,y;
	double xSpeed,ySpeed;
	double angle;
	double angleGoal;
	int xGoal,yGoal;
	int memberOf;
	int gateOf;
	int enzymeOf;
	Status status;
	int ID;
	UnitType type;
	double maxSpeed;
	bool selected;
public:
	Unit();
	Unit( int X, int Y, UnitType t );
	void step();
	void set_goal( int X, int Y );
	void show();
	double getX();
	double getY();
	void select();
	void unselect();
	bool getSelected();
};
Unit::Unit()
{
}
Unit::Unit( int X, int Y, UnitType t )
{
	x = X;
	y = Y;
	xSpeed = 0;
	ySpeed = 0;
	angle = 0;
	angleGoal = 0;
	xGoal = -1;
	yGoal = -1;
	memberOf = -1;
	gateOf = -1;
	enzymeOf = -1;
	status = IDLE;
	ID = unitCurrentID;
	unitCurrentID++;
	if ( unitCurrentID == MAX_UNITS )
	{
		unitCurrentID = 0;
	}
	type = t;
	maxSpeed = 0.5;
	selected = false;
}
void Unit::step()
{
	x += xSpeed;
	y += ySpeed;
	if ( ( abs(xGoal-x)<=1 ) && ( abs(yGoal-y)<=1 ) )
	{
		xSpeed = 0;
		ySpeed = 0;
	}
}
void Unit::set_goal( int X, int Y )
{
	xGoal = X;
	yGoal = Y;
	xSpeed = lengthdir_x( x, y, X, Y, maxSpeed );
	ySpeed = lengthdir_y( x, y, X, Y, maxSpeed );
}
void Unit::show()
{
	switch( type )
	{
	case UT_CIRCLE: DrawCircle( (float)x, (float)y, 10, 20, true, 0.0f, 1.0f, 0.0f ); 
					if ( selected )
					{
						DrawCircle( (float)x, (float)y, 12, 25, false, 1.0f, 0.0f, 0.0f ); 
					}
					break;
	case UT_RECT: glBegin( GL_QUADS );
				  glColor3f( 1.0f, 0.0f, 0.0f );
				  glVertex2i( (GLint)x-10, (GLint)y-5 );
				  glVertex2i( (GLint)x+10, (GLint)y-5 );
				  glVertex2i( (GLint)x+10, (GLint)y+5 );
				  glVertex2i( (GLint)x-10, (GLint)y+5 );
				  glEnd();
				  break;
	case UT_SQUARE: glBegin( GL_QUADS );
					glColor3f( 0.0f, 0.0f, 1.0f );
					glVertex2i( (GLint)x-10, (GLint)y-10 );
					glVertex2i( (GLint)x+10, (GLint)y-10 );
					glVertex2i( (GLint)x+10, (GLint)y+10 );
					glVertex2i( (GLint)x-10, (GLint)y+10 );
					glEnd();
					break;
	default: ;
	}
}
double Unit::getX()
{
	return x;
}
double Unit::getY()
{
	return y;
}
void Unit::select()
{
	selected = true;
}
void Unit::unselect()
{
	selected = false;
}
bool Unit::getSelected()
{
	return selected;
}


And my main:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
int main( int argc, char* args[] )
{
	Unit* units[MAX_UNITS] = {0};
	Group* groups[MAX_GROUPS] = {0};
	Gate* gates[MAX_GATES] = {0};

	bool quit = false;
	int time = 0;
	RoomStatus status = NORMAL;
	units[unitCurrentID] = new Unit( 320, 240, UT_CIRCLE );

	if ( init() == false )
	{
		return 1;
	}

	while ( quit == false )
	{
		time = SDL_GetTicks();
		while ( SDL_PollEvent( &event ) )
		{
			if ( event.type == SDL_QUIT )
			{
				quit = true;
			}
			else if ( event.type == SDL_KEYDOWN )
			{
				if ( event.key.keysym.sym == SDLK_ESCAPE )
				{
					quit = true;
				}
				else if ( event.key.keysym.unicode == (Uint16)'g' )
				{
					status = CREATE_GROUP;
					SDL_WM_SetCaption( "Creating Group", NULL );
				}
				else if ( event.key.keysym.unicode == (Uint16)'l' )
				{
					status = CREATE_GATE;
					SDL_WM_SetCaption( "Creating Gate", NULL );
				}
				else if ( event.key.keysym.unicode == (Uint16)'n' )
				{
					status = NORMAL;
					SDL_WM_SetCaption( "Normal", NULL );
				}
			}
			else if ( event.type == SDL_MOUSEBUTTONDOWN )
			{
				if ( event.button.button == SDL_BUTTON_LEFT )
				{
					if ( status == NORMAL )
					{
						for ( int i = 0; i < unitCurrentID; i++ )
						{
							if ( inCircle( event.button.x, event.button.y, (int)units[i]->getX(), (int)units[i]->getY(), 10 ) )
							{
								units[i]->select();
							}
							else
							{
								units[i]->unselect();
							}
						}
					}
					else if ( status == CREATE_GROUP )
					{ 
						for ( int i = 0; i < unitCurrentID; i++ )
						{
							if ( inCircle( event.button.x, event.button.y, (int)units[i]->getX(), (int)units[i]->getY(), 10 ) )
							{
								groups[groupCurrentID] = new Group( (int)units[i]->getX(), (int)units[i]->getY(), UT_CIRCLE );
							}
						}
					}
				}
				if ( event.button.button == SDL_BUTTON_RIGHT )
				{
					if ( status == NORMAL )
					{
						for ( int i = 0; i < unitCurrentID; i++ )
						{
							if ( units[i]->getSelected() )
							{
								units[i]->set_goal( event.motion.x, event.motion.y );
							}
						}
					}
				}
			}
		}
		for ( int i = 0; i < unitCurrentID; i++ )
		{
			units[i]->step();
		}

		glClear( GL_COLOR_BUFFER_BIT );
		glLoadIdentity();
		for ( int i = 0; i < unitCurrentID; i++ )
		{
			units[i]->show();
		}
		for ( int ii = 0; ii < groupCurrentID; ii++ )
		{
			groups[ii]->show();
		}
		SDL_GL_SwapBuffers();

		if ( time < 1000 / FRAMES_PER_SECOND )
		{
			SDL_Delay( ( 1000 / FRAMES_PER_SECOND ) - time );
		}
	}
	delete [] &units;
	delete [] &groups;
	delete [] &gates;
	clean_up();
	return 0;
}


Last edited on
I don't see anything wrong with line 6, assuming unitCurrentID==[0;MAX_UNITS). Are you sure the constructor for Unit is not causing it?

By the way, you can replace lines 1 to 5 with Unit* units[MAX_UNITS]={0};.
Last edited on
Is unitCurrentId changing at any point in the program?
I think the problem must lie somewhere else.
Did you use the VC++ debugger?
Project->Properties->C/C++->Warning Level = Level 4 might help too.
I don't think the constructor is the problem because it works if I use:
units[0] = new Unit( 320, 240, UT_CIRCLE );
it works.

EDIT:

unitCurrentID does change in the constructor of Unit:
1
2
3
4
5
6
7
8
9
10
11
Unit::Unit( int X, int Y, UnitType t )
{
	//irrelevant code
	ID = unitCurrentID;
	unitCurrentID++;
	if ( unitCurrentID == MAX_UNITS )
	{
		unitCurrentID = 0;
	}
	//More irrelevant code
}


I added more code to the original post.
Last edited on
Where is unitCurrentID being initialized?
Last edited on
At the beginning of the program

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include "SDL.h"
#include "SDL_opengl.h"
#include "math.h"
#include <sstream>
#include <string>

const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;
const int SCREEN_BPP = 32;
const int FRAMES_PER_SECOND = 60;
const int MAX_UNITS = 20;
const int MAX_GROUPS = 10;
const int MAX_GATES = 15;

SDL_Event event;

int unitCurrentID = 0;
int groupCurrentID = 0;
int gateCurrentID = 0;
Topic archived. No new replies allowed.