delete[] operator issue

Hello all,

I'm having some issues with my destructor and delete functions for my enemy array. This is an asteroids-like game. Same functionality. Enemies tick one direction, lower on the x-axis, and begin ticking the other direction. You shoot them. Everything compiles fine. Warnings are listed below:

*Note: I've cut out non-related code due to char limits.

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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
//--------------------------ENEMY CLASS--------------------------------//
class Enemy{
public:
    Enemy(int x,int y)
    {
        xPos = x;
        yPos = y;
        width = 50;
        height = 15;
        box.x = xPos;
        box.y = yPos;
        box.w = width;
        box.h = height;
    }
    SDL_Rect box;

    int getVisible() { return visible; }
    void setVisible(int x) { visible = x; }

private:
    int xPos;
    int yPos;
    int width;
    int height;
    bool visible = true;
};
//-----------------------COLLISION DETECTION---------------------------//
bool collision(SDL_Rect* rec1, SDL_Rect* rec2)
{
    if(rec1->y >= rec2->y + rec2->h)
    {
        return false;
    }
    if(rec1->y + rec1->h <= rec2->y)
    {
        return false;
    }
    if(rec1->x >= rec2->x + rec2->w)
    {
        return false;
    }
    if(rec1->x + rec1->w <= rec2->x)
    {
        return false;
    }
    return true;
}

//-----------------------GLOBAL VARIABLES------------------------------//
void arrayMove();
void moveDown();
void velSwap(unsigned int * X, unsigned int * Y);
int unsigned const opponents = 18;
int unsigned tmpEnemyVel;
int unsigned tmpNEnemyVel;
Enemy * opponent[opponents];
int unsigned const lastOpponent = (opponents - 1);
bool movedown = false;
int unsigned tickCount = 2;
//-----------------------------MAIN------------------------------------//
int main(int argc, char* argv[])
{
    SDL_Init(SDL_INIT_EVERYTHING);
    SDL_Surface *screen, *ship, *enemy, *bullet;
    screen = SDL_SetVideoMode(640,480,32,SDL_SWSURFACE);
    ship = SDL_DisplayFormat(SDL_LoadBMP("ship1.bmp"));
    SDL_SetColorKey(ship, SDL_SRCCOLORKEY, SDL_MapRGB(screen->format, 0xff, 0xff, 0xff));
    enemy = SDL_DisplayFormat(SDL_LoadBMP("enemy2.bmp"));
    SDL_SetColorKey(enemy, SDL_SRCCOLORKEY, SDL_MapRGB(screen->format, 0xff, 0xff, 0xff));
    bullet = SDL_DisplayFormat(SDL_LoadBMP("bullet.bmp"));
    SDL_SetColorKey(bullet, SDL_SRCCOLORKEY, SDL_MapRGB(screen->format, 0xff, 0xff, 0xff));
    bool running = true;
    bool b[3] = {0,0,0};
    bool spent = false;
    bool shot = false;
    Uint32 start;
    int unsigned second = 1000;
    int unsigned fps = 60;
    SDL_Event event;
    Uint32 black = SDL_MapRGB(screen->format,0,0,0);
    Cube * Box = new Cube(125,450,50,35);
    SDL_Rect ammo; ammo.x = ((Box->box.x + (Box->box.w / 2)) - 6); ammo.y = Box->box.y; ammo.w =9; ammo.h =10;
    int tmpTimer = fps;
    int unsigned enemyVel = 5;
    int unsigned NEnemyVel = -5;
    tmpNEnemyVel = NEnemyVel;
    tmpEnemyVel = enemyVel;
    int unsigned paddleVel = 5;
    int unsigned i = 0;
    int unsigned k = 6;
    int unsigned enemyX = 80;
    int unsigned enemyY = 30;
    for(int unsigned row = 0; row < (opponents / 6); row++ )
    {
        for(; i < k; i++ )
        {
           opponent[i] = new Enemy(enemyX,enemyY);
           enemyX = enemyX + 85;
        }
        enemyX = 80;
        enemyY += 35;
        k += 6;
    }
    while(running)
    {

//--------------------------ENEMY MOVEMENT-----------------------------//
            tmpTimer -= 3;
            if(tmpTimer == 0)
            {
                arrayMove();
                tmpTimer = fps;
                tickCount ++;
            }
            if(movedown){
                moveDown();
            }
//--------------------------BULLET MOVEMENT----------------------------//

            if(b[2]){
                shot = true;
                ammo.y -= 15;
            }
            if(ammo.y <= 0)
                spent = true;
            if(spent){
                spent = false;
                shot = false;
                ammo.x = ((Box->box.x + (Box->box.w / 2)) - 6);
                ammo.y = Box->box.y;
                b[2] = 0;
            }
            for(int unsigned v = 0; v < opponents; v++)
            {
                if(collision(&ammo, &opponent[v]->box)){
                    opponent[v]->setVisible(0);
                    spent = true;
                    delete &opponent[v]->box;
                }
            }

//--------------------------SHIP MOVEMENT------------------------------//
            if(b[0]){
                Box->box.x -= paddleVel;
            if(!shot){
                ammo.x -= paddleVel;
            }
            if(Box->box.x <= 0){
                Box->box.x += paddleVel;
                }
            }
            if(b[1]){
                Box->box.x += paddleVel;
                if(!shot){
                ammo.x += paddleVel;
            }
            if(Box->box.x + Box->box.w >= 640){
                Box->box.x -= paddleVel;
                }
            }
//----------------------------RENDER-----------------------------------//
            SDL_FillRect(screen,&screen->clip_rect,black);
            if(!spent){
            SDL_BlitSurface(bullet,NULL,screen,&ammo);
            }
            SDL_BlitSurface(ship, NULL, screen, &Box->box);
            for(int unsigned j = 0; j < opponents; j++)
            {
                if(opponent[j]->getVisible()){
                SDL_BlitSurface(enemy, NULL, screen, &opponent[j]->box);
                }
            }
            SDL_Flip(screen);
//------------------------------FPS------------------------------------//
            if(second/fps>(SDL_GetTicks()-start))
                SDL_Delay(second/fps-(SDL_GetTicks()-start));
    }
//---------------------------TERMINATE---------------------------------//
    SDL_FreeSurface(screen);
    SDL_FreeSurface(ship);
    SDL_FreeSurface(enemy);
    SDL_FreeSurface(bullet);
    SDL_Quit();
    return 0;
}
//--------------------------FUNCTIONS-----------------------------------//
void arrayMove()
{
    for(int unsigned m = 0; m < opponents; m++)
    {
        if(tickCount == 12){
            velSwap(&tmpEnemyVel, &tmpNEnemyVel);
            movedown = true;
            tickCount = 0;
        }
        opponent[m]->box.x -= tmpEnemyVel;
    }
}

void moveDown()
{
    for(int unsigned n = 0; n < opponents; n++)
    {
        opponent[n]->box.y += 25;
        movedown = false;
    }
}

void velSwap(unsigned int * X, unsigned int * Y)
{
    int temp;
    temp = *X;
    *X = *Y;
    *Y = temp;
}


main.cpp|50|warning: non-static data member initializers only available with -std=c++11 or -std=gnu++11 [enabled by default]|

main.cpp|53|warning: no previous declaration for 'bool collision(SDL_Rect*, SDL_Rect*)' [-Wmissing-declarations]|

When I shoot an enemy, the enemy jumps to the left side of the screen, thus creating a barrier between the ammunition and the other ships in the area. The debugger always errors out at line 201 for the delete function. Could someone be kind enough to look over this function and see if I'm properly deleting this object? Also, under my terminate section(lines 241-247). I feel like I'm not properly freeing resources, as when I hit the escape key or the X at the top of the window, to invoke SDL_Quit();, the program hangs up. I would greatly appreciate this! Thanks!
delete &opponent[v]->box; ¿what do you think you are doing there?
By using delete &opponent[v]->box;, releases the object from 'perspective', so to speak. If I don't have it, my ammunition stops at where it should be, only it is no longer being drawn. Does that make sense?
After rereading, I feel I should clarify. delete &opponent[v]->box; does do what it needs to do. It clears the object from the screen instead of just not drawing it, leaving behind a bounding box to collide with. I don't know why it's placing the object to the left though. Shouldn't it just get rid of it altogether?

I'm not sure. I'm not saying it needs to be there, but I can't just delete it because the debugger says it's the problem. I feel like I'm just not knowledgeable enough to know how to implement it properly. Is there anyone willing to shed light on this? I would greatly appreciate it.
delete gives the memory that is previously allocated with new back to the os. So no perspective or whatever magic is involved.

You cannot apply delete simply because box (where the address operator & is applied to) is not created with new.
1
2
3
4
Enemy * opponent[opponents];
opponent[v]; //an Enemy*
opponent[v]->box; //a SDL_Rect
&opponent[v]->box; //a SDL_Rect* 
¿had you allocate `box' with new?
¿had you allocate `box' with new?
¡No! he hasn't
This is great insight. I realized a little more from what you two have mentioned. But I must ask... why does my collision work correctly when it is there, and it(collision) simply fails when I delete that line from my code?
I've corrected my issue by setting opponent[v]'s box coords x,y,w,h to all zeros. It works, but it just seems messy and unprofessional in my opinion. It works for this project, but is there a professional way to go about this?
not that i have the full insight about all you're doing, but when i understand it correctly setVisible() should suffice.
For further collision detection you need to take the visible flag into account and leave everything out of the collision detection that is invisible
setVisible() is only the condition under which it draws it to the screen, not whether or not it exists. Since I'm passing the bounding box into the collision function, even if the object's visibility is false, the bounding box still exists on screen. My bullet literally hits an invisible object and stops, because the object's box was never eliminated, only the drawing of it. I hope that made sense, I'm getting tired. By no means am I fighting my points, I just feel as though I'm sounding very unclear right now.
Wow. Apologies for your efforts, coder777! I just reread that second part and implemented what you suggested:

1
2
3
4
5
6
7
8
9
10
for(int unsigned v = 0; v < opponents; v++)
            {
                if(opponent[v]->getVisible()){
                    if(collision(&ammo, &opponent[v]->box)){
                        opponent[v]->setVisible(0);
                        spent = true;
                        isAlive --;
                    }
                }
            }


This works!! Amazing! That simple... geez.... talk about reinventing the wheel...

Btw, the isAlive--; is a counter for the end of the level. I added that after the fact. Each enemy destroyed takes a tick away from the variable. when it reaches zero, running = false, for now. Until I add more :)

Thanks!! I love this forum!
Topic archived. No new replies allowed.