|
Memory leak in allegro5 |
the_AI
Member #16,314
May 2016
|
Guys im having a kind of memory leak problem due to which my game just crashes after 9-10 seconds. That problem might be in "Board.h" header file, "setText" method or in the "Destructor" in the "Board.cpp" file. I dont know really but it must be there. I am attaching the screen shot to give you guys a good idea about how it looks along with the all the header and cpp files. Any further suggestion for better code and techniques are WELCOME... THANK YOU GUYS and PLEASE PLEASE HELP ME!!! (pardon me for my bad english)... 1
2 MAIN FUNCTION
3
4 #include <iostream>
5 #include <allegro5/allegro5.h>
6 #include <allegro5/allegro_native_dialog.h>
7 #include <allegro5/allegro_color.h>
8 #include <allegro5/allegro_primitives.h>
9 #include <allegro5/allegro_ttf.h>
10 #include <allegro5/allegro_font.h>
11 #include "Board.h"
12 #include "Player.h"
13
14
15 #define SCREEN_WIDTH 800
16 #define SCREEN_HEIGHT 606
17
18
19 using namespace std;
20
21 int main(){
22
23 if(!al_init()){
24 al_show_native_message_box(NULL, "Initializing", "Initializing error!", "Initializing failed", "Got it!", ALLEGRO_MESSAGEBOX_OK_CANCEL);
25 return -1;
26 }
27 ALLEGRO_DISPLAY *display = al_create_display(SCREEN_WIDTH, SCREEN_HEIGHT);
28
29 if(!display){
30 al_show_native_message_box(NULL, "Display", "Display error!", "Display creation failed", "Got it!", ALLEGRO_MESSAGEBOX_OK_CANCEL);
31 return -1;
32 }
33
34 al_init_font_addon();
35 al_init_ttf_addon();
36 al_install_keyboard();
37 al_install_mouse();
38 al_init_primitives_addon();
39
40 bool game_exit = false, draw = false;
41 bool click = false;
42 float x = 0, y = 0;
43
44
45 // Allegro instances and methods
46 ALLEGRO_EVENT_QUEUE *event_queue = al_create_event_queue();
47
48 ALLEGRO_COLOR box_color = al_map_rgb(119,136,153);
49 ALLEGRO_COLOR box_hover_color = al_map_rgb(139,156,173);
50
51 ALLEGRO_COLOR new_game_color = al_map_rgb(34, 177, 76);
52 ALLEGRO_COLOR new_game_hover_color = al_map_rgb(40, 210, 91);
53
54 ALLEGRO_COLOR exit_color = al_map_rgb(237, 28, 36);
55 ALLEGRO_COLOR exit_hover_color = al_map_rgb(255, 79, 87);
56
57 ALLEGRO_COLOR border_color = al_map_rgb(0, 0, 0);
58 ALLEGRO_COLOR caption_color = al_map_rgb(255, 128, 0);
59 ALLEGRO_COLOR score_color = al_map_rgb(235, 235, 235);
60 ALLEGRO_COLOR background = al_map_rgb(200, 191, 231);
61 ALLEGRO_COLOR back_board_color = al_map_rgb(12, 125, 200);
62 ALLEGRO_COLOR font_color = al_map_rgb(0, 0, 0);
63 ALLEGRO_TIMER *timer = al_create_timer(1.0/60);
64
65 ALLEGRO_FONT *OandX = al_load_ttf_font("Ubuntu.ttf", 25, 0);
66 ALLEGRO_FONT *exit_font = al_load_ttf_font("Ubuntu.ttf", 17, 0);
67 ALLEGRO_FONT *new_game_font = al_load_ttf_font("Ubuntu.ttf", 15, 0);
68 ALLEGRO_FONT *player_text[2];
69
70 player_text[0] = al_load_ttf_font("Ubuntu.ttf", 15, 0);
71 player_text[1] = al_load_ttf_font("Ubuntu.ttf", 15, 0);
72
73 al_register_event_source(event_queue, al_get_display_event_source(display));
74 al_register_event_source(event_queue, al_get_keyboard_event_source());
75 al_register_event_source(event_queue, al_get_timer_event_source(timer));
76 al_register_event_source(event_queue, al_get_mouse_event_source());
77
78
79 // Objects
80
81 Player player1;
82 player1.setName("Robert ");
83
84 Player player2;
85 player2.setName("Jane ");
86
87
88 Board box[9];
89 Board caption;
90 Board new_game;
91 Board exit;
92 Board back_board;
93 Board player_board[2];
94
95
96 box[0].drawBorderedBoard(4, 4, 200, 200, 5, 5, box_color, border_color, 2);
97 box[1].drawBorderedBoard(205, 4, 401, 200, 5, 5, box_color, border_color, 2);
98 box[2].drawBorderedBoard(406, 4, 602, 200, 5, 5, box_color, border_color, 2);
99
100 box[3].drawBorderedBoard(4, 205, 200, 401, 5, 5, box_color, border_color, 2);
101 box[4].drawBorderedBoard(205, 205, 401, 401, 5, 5, box_color, border_color, 2);
102 box[5].drawBorderedBoard(406, 205, 602, 401, 5, 5, box_color, border_color, 2);
103
104 box[6].drawBorderedBoard(4, 406, 200, 602, 5, 5, box_color, border_color, 2);
105 box[7].drawBorderedBoard(205, 406, 401, 602, 5, 5, box_color, border_color, 2);
106 box[8].drawBorderedBoard(406, 406, 602, 602, 5, 5, box_color, border_color, 2);
107
108 new_game.drawBorderedBoard(607, 556, 700, 601, 5, 5, new_game_color, border_color, 2);
109 exit.drawBorderedBoard(704, 556, 797, 601, 5, 5, exit_color, border_color, 2);
110
111 // starting the timer
112 al_start_timer(timer);
113
114 while(!game_exit){
115
116 ALLEGRO_EVENT events;
117 al_wait_for_event(event_queue, &events);
118
119 if(events.type == ALLEGRO_EVENT_DISPLAY_CLOSE){
120 game_exit = true;
121 }
122
123 else if(events.type == ALLEGRO_EVENT_KEY_UP){
124 if(events.keyboard.keycode == ALLEGRO_KEY_ESCAPE){
125 game_exit = true;
126 }
127 }
128
129 else if(events.type == ALLEGRO_EVENT_TIMER){
130 draw = true;
131 }
132
133 if(events.type == ALLEGRO_EVENT_MOUSE_AXES){
134 x = events.mouse.x;
135 y = events.mouse.y;
136 }
137
138 else if(events.type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN){
139 if(events.mouse.button & 1){
140 click = true;
141 }
142 }
143
144 if(events.type == ALLEGRO_EVENT_MOUSE_BUTTON_UP){
145 if(events.mouse.button & 1){
146 click = false;
147 }
148 }
149
150 if(draw){
151 draw = false;
152
153 //drawing score, caption and all that boards
154 caption.drawBorderedBoard(607, 3, 797, 50, 5, 5, caption_color, border_color, 2);
155 back_board.drawBorderedBoard(607, 55, 797, 551, 5, 5, back_board_color, border_color, 2);
156 player_board[0].drawBorderedBoard(705, 60, 790, 110, 5, 5, score_color, border_color, 2);
157 player_board[1].drawBorderedBoard(705, 115, 790, 165, 5, 5, score_color, border_color, 2);
158
159
160 // Event handling for buttons and boxes
161
162 // Box 1
163 if(x >= box[0].getX1() && x <= box[0].getX2() && y >= box[0].getY1()
164 && y <= box[0].getY2()){
165 if(click){
166 box[0].onClick(box_color);
167 box[0].setText(box[0].getMiddleX(), box[0].getMiddleY(), 100, "X");
168 }
169
170 else{
171 box[0].onHover(box_hover_color);
172 box[0].setText(box[0].getMiddleX(), box[0].getMiddleY(), 100, "X");
173 }
174 }
175 else{
176 box[0].redrawBorderedBoard();
177 box[0].setText(box[0].getMiddleX(), box[0].getMiddleY(), 100, "X");
178 }
179
180
181 // Box 2
182 if(x >= box[1].getX1() && x <= box[1].getX2() && y >= box[1].getY1()
183 && y <= box[1].getY2()){
184 if(click){
185 box[1].onClick(box_color);
186 }
187 else{
188 box[1].onHover(box_hover_color);
189 }
190 }
191 else
192 box[1].redrawBorderedBoard();
193
194 // Box 3
195 if(x >= box[2].getX1() && x <= box[2].getX2() && y >= box[2].getY1()
196 && y <= box[2].getY2()){
197 if(click){
198 box[2].onClick(box_color);
199 }
200 else{
201 box[2].onHover(box_hover_color);
202 }
203 }
204 else
205 box[2].redrawBorderedBoard();
206
207 // Box 4
208 if(x >= box[3].getX1() && x <= box[3].getX2() && y >= box[3].getY1()
209 && y <= box[3].getY2()){
210 if(click){
211 box[3].onClick(box_color);
212 }
213 else{
214 box[3].onHover(box_hover_color);
215 }
216 }
217 else
218 box[3].redrawBorderedBoard();
219
220 // Box 5
221 if(x >= box[4].getX1() && x <= box[4].getX2() && y >= box[4].getY1()
222 && y <= box[4].getY2()){
223 if(click){
224 box[4].onClick(box_color);
225 }
226 else{
227 box[4].onHover(box_hover_color);
228 }
229 }
230 else
231 box[4].redrawBorderedBoard();
232
233 // Box 6
234 if(x >= box[5].getX1() && x <= box[5].getX2() && y >= box[5].getY1()
235 && y <= box[5].getY2()){
236 if(click){
237 box[5].onClick(box_color);
238 }
239 else{
240 box[5].onHover(box_hover_color);
241 }
242 }
243 else
244 box[5].redrawBorderedBoard();
245
246 // Box 7
247 if(x >= box[6].getX1() && x <= box[6].getX2() && y >= box[6].getY1()
248 && y <= box[6].getY2()){
249 if(click){
250 box[6].onClick(box_color);
251 }
252 else{
253 box[6].onHover(box_hover_color);
254 }
255 }
256 else
257 box[6].redrawBorderedBoard();
258
259 // Box 8
260 if(x >= box[7].getX1() && x <= box[7].getX2() && y >= box[7].getY1()
261 && y <= box[7].getY2()){
262 if(click){
263 box[7].onClick(box_color);
264 }
265 else{
266 box[7].onHover(box_hover_color);
267 }
268 }
269 else
270 box[7].redrawBorderedBoard();
271
272 // Box 9
273 if(x >= box[8].getX1() && x <= box[8].getX2() && y >= box[8].getY1()
274 && y <= box[8].getY2()){
275 if(click){
276 box[8].onClick(box_color);
277 }
278 else{
279 box[8].onHover(box_hover_color);
280 }
281 }
282 else
283 box[8].redrawBorderedBoard();
284
285 // new game button
286 if(x >= new_game.getX1() && x <= new_game.getX2() && y >= new_game.getY1()
287 && y <= new_game.getY2()){
288 if(click){
289 new_game.onClick(new_game_color);
290 }
291
292 else{
293 new_game.onHover(new_game_hover_color);
294 }
295 }
296 else
297 new_game.redrawBorderedBoard();
298
299 // exit button
300 if(x >= exit.getX1() && x <= exit.getX2() && y >= exit.getY1()
301 && y <= exit.getY2()){
302 if(click){
303 exit.onClick(exit_color);
304 game_exit = true;
305 }
306
307 else{
308 exit.onHover(exit_hover_color);
309 }
310 }
311 else
312 exit.redrawBorderedBoard();
313
314
315
316 al_draw_text(OandX, font_color, caption.getMiddleX(),
317 caption.getMiddleY() - al_get_font_line_height(OandX) / 2,
318 ALLEGRO_ALIGN_CENTER, " O & X ");
319
320 al_draw_text(player_text[0], font_color, back_board.getMiddleX(),
321 player_board[0].getMiddleY() - al_get_font_line_height(player_text[0]) / 2,
322 ALLEGRO_ALIGN_RIGHT, player1.getName());
323
324 al_draw_text(player_text[1], font_color, back_board.getMiddleX(),
325 player_board[1].getMiddleY() - al_get_font_line_height(player_text[1]) / 2,
326 ALLEGRO_ALIGN_RIGHT, player2.getName());
327
328 al_draw_text(new_game_font, font_color, new_game.getMiddleX(),
329 new_game.getMiddleY() - al_get_font_line_height(new_game_font) / 2,
330 ALLEGRO_ALIGN_CENTER, "New Game");
331
332 al_draw_text(exit_font, font_color, exit.getMiddleX(),
333 exit.getMiddleY() - al_get_font_line_height(exit_font) / 2,
334 ALLEGRO_ALIGN_CENTER, "Exit!");
335
336 al_flip_display();
337 al_clear_to_color(background);
338 }
339 }
340
341 al_destroy_timer(timer);
342 al_destroy_font(OandX);
343 al_destroy_font(exit_font);
344 al_destroy_font(new_game_font);
345 al_destroy_font(player_text[0]);
346 al_destroy_font(player_text[1]);
347 al_destroy_event_queue(event_queue);
348 al_destroy_display(display);
349
350 return 0;
351 }
352
353
354
355
356
357
358 // CLASS Board.h
359
360 #ifndef BOARD_H
361 #define BOARD_H
362 #include <allegro5/allegro5.h>
363 #include <allegro5/allegro_color.h>
364 #include <allegro5/allegro_ttf.h>
365 #include <allegro5/allegro_font.h>
366
367
368 class Board{
369 public:
370 Board();
371 ~Board();
372 void redraw();
373 void onClick(ALLEGRO_COLOR pressed_color);
374 void onHover(ALLEGRO_COLOR hover_color);
375 void draw(float x1, float y1, float x2, float y2, float rx, float ry,
376 ALLEGRO_COLOR board_color);
377 void redrawBorderedBoard();
378 void drawBorderedBoard(float x1, float y1, float x2, float y2, float rx, float ry,
379 ALLEGRO_COLOR board_color, ALLEGRO_COLOR border_color, float thickness);
380 void setText(float x, float y, float text_size, const char *text);
381
382
383 float getX1();
384 float getY1();
385 float getX2();
386 float getY2();
387 float getWidth();
388 float getHeight();
389 float getMiddleX();
390 float getMiddleY();
391 float getThickness();
392 float getRX();
393 float getRY();
394 float getTextX();
395 float getTextY();
396 float getTextSize();
397 const char *getText();
398 ALLEGRO_COLOR getBoardColor();
399 ALLEGRO_COLOR getBorderColor();
400 ALLEGRO_COLOR getPressedColor();
401 ALLEGRO_COLOR getHoverColor();
402
403
404 protected:
405
406 private:
407 float board_x1, board_y1, board_x2, board_y2, board_rx, board_ry;
408 float text_x, text_y, text_size;
409 float border_thickness;
410 ALLEGRO_COLOR board_color, border_color, pressed_color, hover_color;
411 ALLEGRO_FONT *font;
412 const char *text;
413
414 };
415
416 #endif // BOARD_H
417
418
419 // CPP FILE Board.cpp
420
421 #include "Board.h"
422 #include <allegro5/allegro_primitives.h>
423 #include <iostream>
424
425
426 // constructor
427 Board::Board(){
428
429 board_x1 = 0;
430 board_x2 = 0;
431 board_y1 = 0;
432 board_y2 = 0;
433 board_rx = 0;
434 board_ry = 0;
435 border_thickness = 0.0;
436 text_x = 0;
437 text_y = 0;
438 text_size = 10;
439 text = "";
440 board_color = al_map_rgb(0, 0, 0);
441 border_color = al_map_rgb(0, 0, 0);
442 pressed_color = al_map_rgb(0, 0, 0);
443 hover_color = al_map_rgb(0, 0, 0);
444 }
445
446 // draws bordered board
447 void Board:: drawBorderedBoard(float x1, float y1, float x2, float y2, float rx, float ry,
448 ALLEGRO_COLOR board_color, ALLEGRO_COLOR border_color, float thickness){
449
450 board_x1 = x1;
451 board_x2 = x2;
452 board_y1 = y1;
453 board_y2 = y2;
454 board_rx = rx;
455 board_ry = ry;
456 Board::board_color = board_color;
457 Board::border_color = border_color;
458 border_thickness = thickness;
459
460 al_draw_filled_rounded_rectangle(board_x1, board_y1, board_x2, board_y2,
461 board_rx, board_ry, Board::board_color);
462
463 al_draw_rounded_rectangle(board_x1, board_y1, board_x2, board_y2,
464 board_rx, board_ry, Board::border_color, border_thickness);
465 }
466
467
468 // destructor
469 Board::~Board(){
470 al_destroy_font(Board::font);
471 }
472
473
474 // redraws bordered board
475 void Board::redrawBorderedBoard(){
476
477 al_draw_filled_rounded_rectangle(board_x1, board_y1, board_x2, board_y2,
478 board_rx, board_ry, Board::board_color);
479
480 al_draw_rounded_rectangle(board_x1, board_y1, board_x2, board_y2,
481 board_rx, board_ry, Board::border_color, border_thickness);
482 }
483
484
485 // draws board
486 void Board::draw(float x1, float y1, float x2, float y2, float rx, float ry, ALLEGRO_COLOR board_color){
487
488 board_x1 = x1;
489 board_x2 = x2;
490 board_y1 = y1;
491 board_y2 = y2;
492 board_rx = rx;
493 board_ry = ry;
494 Board::board_color = board_color;
495
496 al_draw_filled_rounded_rectangle(board_x1, board_y1, board_x2, board_y2,
497 board_rx, board_ry, Board::board_color);
498 }
499
500
501 // redraw
502 void Board::redraw(){
503
504 al_draw_filled_rounded_rectangle(board_x1, board_y1, board_x2, board_y2,
505 board_rx, board_ry, Board::board_color);
506 }
507
508
509 // draws pressed button
510 void Board::onClick(ALLEGRO_COLOR pressed_color){
511 Board::pressed_color = pressed_color;
512
513 al_draw_filled_rounded_rectangle(board_x1, board_y1, board_x2, board_y2, board_rx, board_ry,
514 Board::pressed_color);
515
516 al_draw_rounded_rectangle(board_x1, board_y1, board_x2, board_y2, board_rx, board_ry,
517 Board::border_color, border_thickness);
518 }
519
520
521 // on hover
522 void Board::onHover(ALLEGRO_COLOR hover_color){
523 Board::hover_color = hover_color;
524
525 al_draw_filled_rounded_rectangle(board_x1, board_y1, board_x2, board_y2, board_rx,
526 board_ry, Board::hover_color);
527
528 al_draw_rounded_rectangle(board_x1, board_y1, board_x2, board_y2,
529 board_rx, board_ry, Board::border_color, border_thickness);
530 }
531
532
533 // setting text
534 void Board::setText(float x, float y, float text_size, const char* text){
535 text_x = x;
536 text_y = y;
537 Board::text_size = text_size;
538 Board::text = text;
539
540 font = al_load_ttf_font("Ubuntu.ttf", Board::text_size, 0);
541
542 al_draw_text(Board::font, al_map_rgb(0, 0, 0), x, y - al_get_font_line_height(Board::font)/2,
543 ALLEGRO_ALIGN_CENTER, text);
544 }
545
546
547 // getter methods
548 float Board::getX1(){
549 return Board::board_x1;
550 }
551
552 float Board::getY1(){
553 return Board::board_y1;
554 }
555
556 float Board::getX2(){
557 return Board::board_x2;
558 }
559
560 float Board::getY2(){
561 return Board::board_y2;
562 }
563
564 float Board::getRX(){
565 return board_rx;
566 }
567
568 float Board::getRY(){
569
570 return board_ry;
571 }
572 float Board::getWidth(){
573 return (board_x2 - board_x1);
574 }
575
576 float Board::getHeight(){
577 return (board_y2 - board_y1);
578 }
579
580 float Board::getMiddleX(){
581 return (board_x1 + (board_x2 - board_x1) / 2);
582 }
583
584 float Board::getMiddleY(){
585 return (board_y1 + (board_y2 - board_y1) / 2);
586 }
587
588 float Board::getThickness(){
589 return border_thickness;
590 }
591
592 float Board::getTextX(){
593 return text_x;
594 }
595
596 float Board::getTextY(){
597 return text_y;
598 }
599
600 float Board::getTextSize(){
601 return Board::text_size;
602 }
603
604 const char *Board::getText(){
605 return Board::text;
606 }
607
608 ALLEGRO_COLOR Board::getBoardColor(){
609 return board_color;
610 }
611
612 ALLEGRO_COLOR Board::getBorderColor(){
613 return Board::border_color;
614 }
615
616 ALLEGRO_COLOR Board::getPressedColor(){
617 return Board::pressed_color;
618 }
619
620 ALLEGRO_COLOR Board::getHoverColor(){
621 return Board::hover_color;
622 }
623
624
625
626
627
628
629
630 // CLASS Player.h
631
632 // This class is still in progress. I am giving the entire code that i've done
633
634
635 #ifndef PLAYER_H
636 #define PLAYER_H
637 #include <string>
638
639 using namespace std;
640
641 class Player
642 {
643 public:
644 Player();
645 ~Player();
646 void setName(const char *name);
647 const char *getName();
648 void setScore(float score);
649 float getScore();
650 void setTurn(bool turn);
651 bool getTurn();
652
653 private:
654 const char *name;
655 float score;
656 bool turn;
657 };
658
659 #endif // PLAYER_H
660
661
662
663 // CPP FILE Player.cpp
664
665
666 #include "Player.h"
667 #include <iostream>
668
669 using namespace std;
670
671 Player::Player(){
672
673 name = "Player";
674 score = 0.0;
675 turn = false;
676 }
677
678 Player::~Player(){
679 Player::name = "";
680 }
681
682
683 //
684 void Player::setName(const char *name){
685 Player::name = name;
686 }
687
688
689 //
690 const char *Player::getName(){
691 return Player::name;
692 }
693
694
695 //
696 void Player::setScore(float score){
697 Player::score = score;
698 }
699
700
701 //
702 float Player::getScore(){
703 return Player::score;
704 }
705
706
707 //
708 void Player::setTurn(bool turn){
709 Player::turn = turn;
710 }
711
712
713 //
714 bool Player::getTurn(){
715 return Player::turn;
716 }
|
David Couzelis
Member #10,079
August 2008
|
Waaaait a minute... I understand that your game is crashing after 10 seconds. But how do you know it's because of a memory leak? |
jmasterx
Member #11,410
October 2009
|
You create the board font EVERY TIME you setText, but you only DESTROY the font once in the destructor... Allegro 5 has a serious memory leak here Agui GUI API -> https://github.com/jmasterx/Agui |
Chris Katko
Member #1,881
January 2002
|
I don't see anything outright obvious. Upload the whole thing. (Preferably with any other files needed to run, since you say it's crashing at run-time.) Valgrind is amazingly useful and free, but it looks like you're stuck on Windows. If you can use a Linux machine or VM, go for Valgrind. It's a dynamic code checker. It runs your code in a fake CPU (like an emulator) while checking for an impressive amount of error conditions. Otherwise, there are some Valgrind alternatives listed here: http://stackoverflow.com/questions/413477/is-there-a-good-valgrind-substitute-for-windows There are also static code checkers. Static code checkers cannot find run-time errors that don't happen every time (two threads that only crash when one thread is slightly ahead or behind the other thread), but they can still help find the majority of errors. (Static analyzers also check ALL code, whereas dynamic ones only see the code path you actually run--so a function that is never called will never be checked by a dynamic checker.) Cppcheck is a very prominent checker. As for general rules of thumb: - Check and recheck all pointers. Check where they're made, assigned, AND changed. Check task manager for your program. (Hotkey: Windows Key + Escape) If the memory is leaking in a loop, it will keep grabbing memory over time and show up in task manager. [edit] Damn, beaten! That's a good catch! I saw the font and didn't even think twice to check where it was in the codepath. font = al_load_ttf_font("Ubuntu.ttf", Board::text_size, 0);
-----sig: |
jmasterx
Member #11,410
October 2009
|
Also, in your player destructor: the string "Player" is allocated in static storage and therefore never needs to be destroyed setting the name = ""; mearly assigns yet another string from static storage and doesnt destroy anything. Agui GUI API -> https://github.com/jmasterx/Agui |
the_AI
Member #16,314
May 2016
|
i know that it is memory leak problem cuz same thing happened once and thanks for answering... David couzelis Thanks for pointing out the serious problem. i'll look forward for it and reply soon if it solves the problem.... jmasterx Yes you are right, i am stuck with the windows and with my laptop too. Its too slow though and i cant run any VM efficiently, so my bad luck but i'll look for the Valgrind... Chris Katko AND AGAIN, THANKS FOR HELPING ME GUYS..... |
jmasterx
Member #11,410
October 2009
|
This will let you reply soon. Agui GUI API -> https://github.com/jmasterx/Agui |
|