Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Instance of a class inside some other class.

This thread is locked; no one can reply to it. rss feed Print
Instance of a class inside some other class.
Gnamra
Member #12,503
January 2011
avatar

Hello, my program keeps crashing all the time. The VC10++ debugger won't help me either. In my main I create a Player class and a Game class to handle logic.
And when I get into the game loop it sometimes crashes instantly, but often not. I send the address of the player class and an array of Platform classes to the game.update to do collision detections and other stuff.
The crash happens inside game.update at the player->move(&events);

main.cpp

#SelectExpand
1#include "Game.h" 2#include "Player.h" 3#include "Drawengine.h" 4#include "Pistol.h" 5 6Platform **platform; 7 8void setPlatforms() 9{ 10 platform = new Platform*[5]; 11 12 platform[0] = new Platform; 13 platform[1] = new Platform; 14 platform[2] = new Platform; 15 platform[3] = new Platform; 16 platform[4] = new Platform; 17 18}; 19 20int main() 21{ 22 Player player; 23 Game game; 24 Drawengine draw(1280, 720); 25 setPlatforms(); 26 platform[0]->setDimensions(0.0, 570.0, 1280.0, 100.0); 27 platform[1]->setDimensions(200.0, 450.0, 50.0, 10.0); 28 platform[2]->setDimensions(500.0, 450.0, 50.0, 10.0); 29 platform[3]->setDimensions(800.0, 450.0, 50.0, 10.0); 30 31 platform[0]->visible = false; 32 33 bool done = false; 34 35 while(!done) 36 { 37 al_clear_to_color(al_map_rgb(0,0,0)); 38 game.update(&player, platform); 39 40 draw.drawBackground(); 41 draw.drawStats(&player); 42 draw.drawPlatforms(platform); 43 if(player.getKey(2)) draw.playerJump(&player); 44 else if(player.getKey(0)) draw.playerWalkLeft(&player); 45 else if(player.getKey(1)) draw.playerWalkRight(&player); 46 else draw.playerIdle(&player); 47 if(draw.showBoxes) draw.drawPlayerBoxes(&player); 48 49 al_flip_display(); 50 al_rest(0.030); 51 } 52 53}

game.h

#SelectExpand
1#ifndef GAME_H 2#define GAME_H 3#include <allegro5\allegro.h> 4#include <allegro5\allegro_font.h> 5#include <allegro5\allegro_ttf.h> 6#include <allegro5\allegro_primitives.h> 7#include "Player.h" 8#include "Platforms.h" 9 10class Game 11{ 12public: 13 Game(); 14 ALLEGRO_EVENT_QUEUE *event_queue; 15 ALLEGRO_EVENT events; 16 17 void update(Player *p, Platform **platform); 18 19private: 20 int worldWidth; 21 int worldHeight; 22 23protected: 24 25 26};

game.cpp

#SelectExpand
1#include "Game.h" 2#include "Collision.h" 3#include "Drawengine.h" 4#include <allegro5\allegro_native_dialog.h> 5#include <allegro5\allegro_image.h> 6 7 8#include <iostream> 9 10Game::Game() 11{ 12 if(!al_init()) 13 { 14 al_show_native_message_box(NULL, NULL, NULL, "Could not initialize Allegro 5 ", NULL, NULL); 15 } 16 al_install_keyboard(); 17 18 event_queue = NULL; 19 event_queue = al_create_event_queue(); 20 if(!event_queue) 21 { 22 std::cout << "failed to create event queue" << std::endl; 23 } 24 al_register_event_source(event_queue, al_get_keyboard_event_source()); 25 worldHeight = 1000; 26 worldWidth = 1000; 27}; 28 29void Game::update(Player *p, Platform **platform) 30{ 31 32 //========================================================== 33 //========================INPUT============================= 34 al_wait_for_event_timed(event_queue, &events, 0.001); 35 p->Move(&events); 36 37 //set position of player to current position + velocity 38 p->update(); 39 if(p->getKey(4))Drawengine::showBoxes = false; 40 if(p->getKey(5))Drawengine::showBoxes = true; 41 42 43 //set position of player to current position + velocity 44 // if player is under the floor 45 if(p->getY() >= 569.0 && p->jumping || p->getY() >= 569.0) 46 { 47 p->setVel_Y(0); 48 p->setY(400); 49 p->jumping = false; 50 p->falling = false; 51 } 52 53 if(p->falling)p->setVel_Y(p->getVel_Y() + 1); 54 if(p->falling && p->getY() == 400.0) p->falling = false; 55 56 57 //========================================================== 58 //========================COLLISION========================= 59 for(int check = 0; check < 5; check++) 60 { 61 62 if(platform[check]->isActive == true) 63 { 64 if(Collision::collisionCheck(p, platform[check])){ 65 if(Collision::checkLegs(p, platform[check])) 66 { 67 p->hitHead(); 68 p->setY(platform[check]->getY() - p->getSY() + 1); 69 p->falling = false; 70 p->jumping = false; 71 } 72 else if(Collision::checkHead(p, platform[check])) 73 { 74 p->hitHead(); 75 p->setY(platform[check]->getY() + platform[check]->getSY() + 5); 76 p->falling = true; 77 p->jumping = true; 78 } 79 else if(Collision::checkRightBody(p, platform[check])) 80 { 81 if(p->getY() < (platform[check]->getY() + platform[check]->getSY())) 82 { 83 p->hitWall(); 84 p->setX(platform[check]->getX() - p->getSX()); 85 if(p->getY() + p->getSY() != platform[check]->getY() + platform[check]->getSY()){ 86 p->falling = true; 87 p->jumping = true; 88 } 89 } 90 } 91 else if(Collision::checkLeftBody(p, platform[check])) 92 { 93 if(p->getY() < (platform[check]->getY() + platform[check]->getSY())) 94 { 95 p->hitWall(); 96 p->setX(platform[check]->getX() + platform[check]->getSX()); 97 if(p->getY() + p->getSY() != platform[check]->getY() + platform[check]->getSY()){ 98 p->falling = true; 99 p->jumping = true; 100 } 101 } 102 } 103 else 104 { 105 Collision::isLeft = false; 106 Collision::isRight = false; 107 Collision::isTop = false; 108 Collision::isLegs = false; 109 110 }; 111 } 112 } 113 if( !Collision::isLeft && !Collision::isRight && !Collision::isTop && !Collision::isLegs) p->falling = true; 114 } 115} 116 117#endif

Player.cpp

#SelectExpand
1#include "Player.h" 2#include <iostream> 3 4Player::Player() 5{ 6 gun = new Pistol; 7 X = 100.0; 8 Y = 200.0; 9 vel_X = 0.0; 10 vel_Y = 0.0; 11 SX = 64.0; 12 SY = 64.0; 13 14 HX1 = X + 10.0; 15 HX2 = X + getSX() - 10.0; 16 HY1 = Y; 17 HY2 = Y + 20.0; 18 19 LBX1 = X; 20 LBX2 = X + 20.0; 21 LBY1 = Y + 10.0; 22 LBY2 = Y + getSY() - 10.0; 23 24 RBX1 = X + getSX() - 10.0; 25 RBX2 = X + getSX(); 26 RBY1 = Y + 20.0; 27 RBY2 = Y + getSY() - 10.0; 28 29 LX1 = X + 20.0; 30 LX2 = X + getSX() - 20.0; 31 LY1 = Y + getSY() - 20.0; 32 LY2 = Y + getSY(); 33 34 falling = true; 35 jumping = true; 36 key[0] = false; // left 37 key[1] = false; // right 38 key[2] = false; // up 39 key[3] = false; // down 40 key[4] = false; 41 key[5] = false; 42 key[6] = false; 43}; 44 45 46void Player::update() 47{ 48 setX(getX() + vel_X); 49 setY(getY() + vel_Y); 50 51 HX1 = getX() + 10.0; 52 HX2 = getX() + getSX() - 10.0; 53 HY1 = getY(); 54 HY2 = getY() + 20.0; 55 56 LBX1 = getX(); 57 LBX2 = getX() + 20.0; 58 LBY1 = getY() + 10.0; 59 LBY2 = getY() + getSY() - 10.0; 60 61 RBX1 = getX() + getSX() - 10.0; 62 RBX2 = getX() + getSX(); 63 RBY1 = getY() + 20.0; 64 RBY2 = getY() + getSY() - 10.0; 65 66 LX1 = getX() + 20.0; 67 LX2 = getX() + getSX() - 20.0; 68 LY1 = getY() + getSY() - 20.0; 69 LY2 = getY() + getSY(); 70 71}; 72 73 void Player::Move(ALLEGRO_EVENT* events) 74{ 75 if(events->type == ALLEGRO_EVENT_KEY_DOWN) 76 { 77 if(events->keyboard.keycode == ALLEGRO_KEY_LEFT){ 78 key[0] = true; 79 } 80 else if(events->keyboard.keycode == ALLEGRO_KEY_RIGHT){ 81 key[1] = true; 82 } 83 else if(events->keyboard.keycode == ALLEGRO_KEY_UP){ 84 key[2] = true; 85 } 86 else if(events->keyboard.keycode == ALLEGRO_KEY_DOWN){ 87 key[3] = true; 88 } 89 else if(events->keyboard.keycode == ALLEGRO_KEY_O){ 90 key[4] = true; 91 } 92 else if(events->keyboard.keycode == ALLEGRO_KEY_P){ 93 key[5] = true; 94 } 95 else if(events->keyboard.keycode == ALLEGRO_KEY_SPACE){ 96 key[6] = true; 97 } 98 } 99 100 101 if(events->type == ALLEGRO_EVENT_KEY_UP) 102 { 103 if(events->keyboard.keycode == ALLEGRO_KEY_LEFT){ 104 key[0] = false; 105 } 106 else if(events->keyboard.keycode == ALLEGRO_KEY_RIGHT){ 107 key[1] = false; 108 } 109 else if(events->keyboard.keycode == ALLEGRO_KEY_UP){ 110 key[2] = false; 111 } 112 else if(events->keyboard.keycode == ALLEGRO_KEY_DOWN){ 113 key[3] = false; 114 } 115 else if(events->keyboard.keycode == ALLEGRO_KEY_O){ 116 key[4] = false; 117 } 118 else if(events->keyboard.keycode == ALLEGRO_KEY_P){ 119 key[5] = false; 120 } 121 else if(events->keyboard.keycode == ALLEGRO_KEY_SPACE){ 122 key[6] = false; 123 } 124 } 125 126 127 if(key[0] && vel_X > -7.0) moveLeft(); 128 if(key[1] && vel_X < 7.0) moveRight(); 129 if(key[2] && !jumping) Jump(); 130 if(key[6]) gun->fire(); 131 if(!key[0] && vel_X < 0) vel_X += 1; 132 else if(!key[1] && vel_X > 0) vel_X -= 1; 133} 134 135void Player::Jump() 136{ 137 vel_Y -= 15; 138 jumping = true; 139 falling = true; 140} 141 142void Player::moveLeft() 143{ 144 vel_X -= 1; 145}; 146 147void Player::moveRight() 148{ 149 vel_X += 1; 150}; 151 152void Player::hitHead() 153{ 154 vel_Y = 0; 155}; 156 157void Player::hitWall() 158{ 159 vel_X = 0; 160}; 161 162 163 164float Player::getX() 165{ 166 return X; 167} 168 169float Player::getY() 170{ 171 return Y; 172} 173 174float Player::getSX() 175{ 176 return SX; 177} 178 179float Player::getSY() 180{ 181 return SY; 182} 183 184void Player::setY(float y) 185{ 186 Y = y; 187} 188 189void Player::setX(float x) 190{ 191 X = x; 192} 193 194void Player::setVel_X(float x) 195{ 196 vel_X = x; 197} 198 199void Player::setVel_Y(float y) 200{ 201 vel_Y = y; 202} 203 204float Player::getVel_Y() 205{ 206 return vel_Y; 207} 208 209float Player::getVel_X() 210{ 211 return vel_X; 212} 213 214char* Player::getprintable(int i) 215{ 216 char cVal[32]; 217 sprintf_s(cVal,"%f", i); 218 return cVal; 219} 220 221char* Player::getprintable(float f) 222{ 223 char cVal[32]; 224 sprintf_s(cVal,"%f", f); 225 return cVal; 226} 227 228char* Player::getprintable(bool b) 229{ 230 if(b)return "true"; 231 else return "false"; 232}

player.h

#SelectExpand
1 2#ifndef PLAYER_H 3#define PLAYER_H 4 5#include <allegro5\allegro.h> 6#include "Weapons.h" 7#include "Pistol.h" 8#include <cstdio> 9 10class Player 11{ 12public: 13 Player(); 14 void Move(ALLEGRO_EVENT *events); 15 void Jump(); 16 void moveRight(); 17 void moveLeft(); 18 bool jumping; 19 bool falling; 20 void update(); 21 Pistol *gun; 22 ALLEGRO_EVENT lastEvent; 23 24 float getX(); 25 float getY(); 26 float getSX(); 27 float getSY(); 28 float getVel_X(); 29 float getVel_Y(); 30 char* getprintable(int i); 31 char* getprintable(float f); 32 char* getprintable(bool b); 33 void hitWall(); 34 void hitHead(); 35 void setX(float x); 36 void setY(float y); 37 void setVel_X(float x); 38 void setVel_Y(float y); 39 bool key[7]; 40 bool getKey(int i){ 41 return key[i]; 42 }; 43 44 char* keysDown(int i){ 45 if(key[i] == true) return " true"; 46 else return " false"; 47 }; 48 49 50 float HX1; 51 float HX2; 52 float HY1; 53 float HY2; 54 float LBX1; 55 float LBX2; 56 float LBY1; 57 float LBY2; 58 float RBX1; 59 float RBX2; 60 float RBY1; 61 float RBY2; 62 float LX1; 63 float LX2; 64 float LY1; 65 float LY2; 66 float X; 67 float Y; 68 float SX; 69 float SY; 70 float vel_X; 71 float vel_Y; 72}; 73 74 75#endif

the here's the Pistol.h

#SelectExpand
1#ifndef PISTOL_H 2#define PISTOL_H 3 4#include "Bullet.h" 5#include <iostream> 6 7class Pistol 8{ 9public: 10 Pistol(); 11 Bullet ** bullets; 12 13 int bulletType; 14 float bulletVelocityX; 15 float bulletVelocityY; 16 float fireRate; 17 float reloadTime; 18 int magazineSize; 19 int bulletsShot; 20 void calcDamage(float mass) 21 { 22 damage = bulletVelocityX * mass * 10; //kgm/s 23 }; 24 float damage; 25 26 void fire(); 27}; 28 29#endif

Pistol.cpp

#SelectExpand
1#include "Pistol.h" 2 3Pistol::Pistol() 4{ 5 bulletType = 0; 6 bulletVelocityX = 20.0; 7 bulletVelocityY = 0.0; 8 fireRate = 1.0; 9 reloadTime = 2.0; 10 magazineSize = 12; 11 bulletsShot = 0; 12 bullets = new Bullet*[12]; 13}; 14 15void Pistol::fire() 16{ 17 for(int i = 0; i < magazineSize; i++) 18 { 19 if(!bullets[i]->isActive) 20 { 21 bullets[i] = new Bullet(bulletVelocityX, bulletVelocityY, bulletType); 22 bulletsShot++; //this will be used for reloading if I decide to do that. 23 calcDamage(bullets[i]->mass); 24 std::cout << "Bam!" << std::endl; 25 } 26 } 27};

And the bullet class is quite small, so I doubt that's the problem but here it is anyways.

bullet.h

#SelectExpand
1#ifndef BULLET_H 2#define BULLET_H 3 4class Bullet 5{ 6public: 7 Bullet(float vX, float vY, int type); 8 9 float x, y; 10 int type; 11 float velX, velY; 12 float mass; //in kilogram 13 bool isActive; 14}; 15 16#endif

bullet.cpp

#SelectExpand
1#include "Bullet.h" 2 3Bullet::Bullet(float vX, float vY, int bType) 4{ 5 this->velX = vX; 6 this->velY = vY; 7 mass = 0.01; // Kilogram 8 this->type = bType; 9 isActive = true; 10};

weapon_S
Member #7,859
October 2006
avatar

Gnamra said:

The VC10++ debugger won't help me either.

Then you need to learn to use it better. (It does sound like it helped you somewhat.)

Quote:

Bullet ** bullets;

Bad idea. I don't see you checking for your magical number 12 either. That could very well crash. I.e. if you fire more than 12 bullets.

Quote:

if(!bullets[bulletsShot]->isActive)
{
bullets[bulletsShot] = new Bullet(bulletVelocityX, bulletVelocityY, bulletType);

Memory leak. Remove the "new"... Or better yet: rethink how exactly you want to store your bullets first.

Gnamra
Member #12,503
January 2011
avatar

Oh the number 12 comes from magazineSize variable, forgot to edit that. I want all of the bullets to be separate objects, also when a bullet hit something it would get destroyed I just haven't gotten to that part yet.

But why is an array of objects a bad idea? The array size would be different depending on how big the magazine was, I had a for(int i = 0; i < magazineSise;i++) which would check if bullet[i] was already active, if it was then it would continue until it found one not active and create one there.

The reason I want the bullets to be objects is that it would make it easier to mess with them when they're in the air, also I will be adding different types of damage and other fun stuff.

The debugger did help me a bit, and I did learnt to use it a bit better the hours I've been trying to fix the crash. Thank you for your help, but it would be really helpful if someone would elaborate why it is a bad idea to use object array, was it because of the memory leak and if I fired more bullets than there was size for in the array?

I've never tried to have a class create an instance of some other class in the constructor, is that different in any way? I've used object arrays before and they've never been a problem before.

Arvidsson
Member #4,603
May 2004
avatar

I would recommend using a std::vector to store your bullets instead of a multidimensional array. This won't put any restrictions on how many bullets can be fired but you can easily change this so you can't fire more bullets than what the magazine size allows.

There is too little code to exactly say what might be wrong. What does the backtrace of the debugger tell you?

Stas B.
Member #9,615
March 2008

void Pistol::fire()
{
  if(!bullets[bulletsShot]->isActive)
  {
    bullets[bulletsShot] = new Bullet(bulletVelocityX, bulletVelocityY, bulletType);
    calcDamage(bullets[bulletsShot]->mass);
    std::cout << "Bam!" << std::endl;
  }
  bulletsShot++;
};

This code could easily lead to out-of-bounds array access and cause memory corruption, which would result in the random crashes you've described. Add a check to make sure 'bulletsShot' is in the valid range.

There's nothing technically wrong with using arrays of objects or object pointers, but arrays in general can lead to bugs that are notoriously hard to track down because they let you silently corrupt memory if you're not careful. It may lead to random crashes at random parts of the program that have nothing to do with the source of the bug. As rule of thumb, use vectors unless you have a good reason not to. They offer additional safety and features. Note that vectors have a '[]' operator like arrays, but it doesn't check for out-of-bounds access and is as dangerous as plain array access. Use the 'at' method.

In any case, I think your design isn't optimal. When a bullet leaves the gun, it belongs to the world. The gun shouldn't be responsible for updating the bullet positions or for checking if they collide with anything. It's the job of the world object.

Gnamra
Member #12,503
January 2011
avatar

I have updated the Pistol.cpp to have the loop which will make sure that no out of bound business happens, and I've added much more code to the first post.

In the game.cpp the debugger gives me:
Unhandeled exception at 0x779e15de in Allegro.exe: 0xC0000005: Access violation reading location 0xbaadf025.

and then shows me that the next statement is p->update(), so that means it's something in p->move(&events) that is causing it to crash, which is where the gun->fire() is located and it crashes instantly when I press space which makes it execute gun->fire(). This is why I think the fault is located within the gun class, or the how I'm creating instances of classes inside constructors.

Also I will look into vectors.

Also about my design, the gun wont be responsible it will just create a bullet object and give it it's values after that it's game class which will be messing with the bullets trajectory and checking for collision, almost all the collision code is in the collision.h and .cpp but I do not think they are relevant right now, I will also add a separate class for controls so I can clean up the player class.

Stacktrace:

#SelectExpand
1 ntdll.dll!779e15de() 2 [Frames below may be incorrect and/or missing, no symbols loaded for ntdll.dll] 3 ntdll.dll!779e15de() 4 ntdll.dll!779d014e() 5 d3d9.dll!742cd952() 6 d3d9.dll!742cd9d5() 7 d3d9.dll!742c4cd8() 8 d3d9.dll!742cd8f4() 9 atiu9pag.dll!701c1b2f() 10 ntdll.dll!779dfd71() 11 KernelBase.dll!760e31bb() 12 allegro-5.0.6-monolith-md.dll!5053e68f() 13 allegro-5.0.6-monolith-md.dll!5053eb96() 14> Allegro.exe!Game::update(Player * p) Line 38 C++ 15 Allegro.exe!main() Line 40 C++ 16 Allegro.exe!pre_cpp_init() Line 298 + 0x27 bytes C 17 msvcr100.dll!5ea7263d() 18 Allegro.exe!__tmainCRTStartup() Line 555 + 0x17 bytes C 19 kernel32.dll!75fd339a() 20 ntdll.dll!779f9ef2() 21 ntdll.dll!779f9ec5()

Stas B.
Member #9,615
March 2008

Oh, actually, I see the problem now.
When you create the bullet pointer array, it's filled with garbage. Then you treat that garbage like valid pointers and try to read the 'isActive' field, so you get a segfault.

What you're doing doesn't really make much sense.
Why does the ability to shoot new bullets depend on whether the old ones are alive?
Why are the bullet pointers not stored in a list in the game class with the rest of your objects? The gun has nothing to do with the bullets after they've been created.
If you really must insist to store the bullets in the gun object, why do you need an array of pointers? Just make an array of bullets and mark them all as dead initially. This will prevent your crash. ???

Gnamra
Member #12,503
January 2011
avatar

Stas B. said:

When you create the bullet pointer array, it's filled with garbage. Then you treat that garbage like valid pointers and try to read the 'isActive' field, so you get a segfault.

I was actually thinking about that, and I knew that the isActive would be filled with crap, but I thought at worst it would give me some false positives. I will immediately start to rewrite the Pistol class.

Quote:

What you're doing doesn't really make much sense.
Why does the ability to shoot new bullets depend on whether the old ones are alive?
Why are the bullet pointers not stored in a list in the game class with the rest of your objects? The gun has nothing to do with the bullets after they've been created.

I wanted to check the the array so I wouldn't overwrite any of them, and I haven't gotten to the game class / collision detection part yet, right now I just want to make sure that it fires once that is done I'll remove the memory leak and add collision detection.

Quote:

If you really must insist to store the bullets in the gun object, why do you need an array of pointers? Just make an array of bullets and mark them all as dead initially. This will prevent your crash.

Inexperience, I really don't know any other way to create new objects. If I did bullet = new bullet when he fired then all of the instances of it would be called bullet, and I'm not sure if the second time he fired it would crash, overwrite the first one or just not compile at all. Also, I think I got the idea from Unity when I was checking it out and playing one of the demos, when the player shot it would cycle through a list and when the bullets hit something they were marked as dead on the list.

I changed the pistol.fire() to and removed the bullet array.

void Pistol::fire()
{
  Bullet bullet(bulletVelocityX, bulletVelocityY, bulletType);
  bulletsShot++; //this will be used for reloading if I decide to do that.
  calcDamage(bullet.mass);
  std::cout << "Bam!" << std::endl;
};

It did fix the crashes, I'm not sure what it does. Is it creating a lot of bullet objects who are all called bullet? or is it creating one, then replacing it when the next one is created. Also, isn't this a memory leak aswell? And I will try to figure out a way to create and destroy the bullets in the Game class, it would make it much easier to deal with them.

Also, I wanted to have an abstract weapon class, where all the different weapons inherited from the weapons class, then I could have a weapon pointer point to the different weapon objects when the player changed weapons. Is there any problem with this?

Stas B.
Member #9,615
March 2008

Gnamra said:

I was actually thinking about that, and I knew that the isActive would be filled with crap, but I thought at worst it would give me some false positives. I will immediately start to rewrite the Pistol class.

It depends on whether the garbage pointer happens to point at a location that belongs to your program (in which case you'll read a random number) or another program (that's a segmentation fault and will make you crash).

Now, I don't really understand what you're talking about in the rest of your post, but what I'm trying to say is that a bullet is a game object like any other and should be treated as such. The gun just creates one, adds it to the big list of game objects and forgets about it. If you don't have a Game class yet that holds such a list, you should create one first because everything else depends on it.

Gnamra
Member #12,503
January 2011
avatar

I suck at explaining, I know :P What I need to know is:

When it fires, then it creates a Bullet object, called bullet right?
But when it is fired the second time, what happens to the first Bullet object? They both have the same name, is it destroyed or are there two Bullet objects who are both called bullet.

Stas B.
Member #9,615
March 2008

Gnamra said:

When it fires, then it creates a Bullet object, called bullet right?
But when it is fired the second time, what happens to the first Bullet object? They both have the same name, is it destroyed or are there two Bullet objects who are both called bullet.

If you create an object inside a function without the 'new' keyword, it lives on the stack and dies as soon as you leave the function.

If you create an object inside a function with the 'new' keyword, you hold its address in a temporary pointer that dies as soon as you leave the function. The object itself lives but you can't do anything with it (not even destroy it). This is called a memory leak.

Currently, you keep pointers to the bullet objects you create inside an array that is a member of the Pistol class. This is bad because:

1. The pistol object doesn't need to refer to the bullets, so it shouldn't store pointers to them.

2. The game manager object that needs to refer to the bullets should be able to do that directly, not through the pistol object.

3. You should be able to create and destroy bullets freely, so the proper data type is a list.

In short, you should not store bullet pointers inside an array that belongs to the pistol object. You should store bullet pointers inside a general list of game entities that belongs to some kind of game entity manager.

A quick and dirty fix for your problem would be to create an array of objects, not object pointers.

#SelectExpand
1 class Bullet { 2 bool isActive; 3 float vx, vy; 4 int type; 5 6 Bullet() 7 { 8 isActive = false; 9 } 10 11 Bullet(float vx, float vy, int type) 12 { 13 this->vx = vx; 14 this->vy = vy; 15 this->type = type; 16 this->active = true; 17 } 18 }; 19 20 class Pistol { 21 Bullet bulletArray[12]; 22 23 void fire() 24 { 25 for(int i = 0; i < 12; i++) 26 if(!bulletArray[i].isActive) 27 { 28 bulletArray[i] = Bullet(vx, vy, type); 29 break; 30 } 31 } 32 };

However, I would strongly advise against actually doing that. It will stop your game from crashing, but it's just a temporary quick fix. Your real problem is a design problem.

Gnamra
Member #12,503
January 2011
avatar

Ofcourse! How could I have forgotten that everything made inside a function is local(unless theres some way to make it global), thanks! You reminded me of something very important, I will get to work at once. Thank you very much for all the help! ;D

Go to: