Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Application crashes on exit

This thread is locked; no one can reply to it. rss feed Print
Application crashes on exit
Iluvatar
Member #7,998
November 2006

Hello.

I actually have a problem with a program I'm writing in C++. No problem to compile but at execution, it crashes (Segmentation Fault) at the end of execution.

The code of this early program is at this adress (another forum for allegro)(I didn't manage to upload the files here):
http://www.developpez.net/forums/showthread.php?p=1539606#post1539606
(DangerousBowlOfJelly is my pseudo on this forum)

My environnement : WinXP + Code::Blocks 1.0 + MinGW32.

Any help would be nice.

Thanks

Il.

Arthur Kalliokoski
Second in Command
February 2005
avatar

I looked at the French instructions, didn't understand, saw the zip link, clicked on that and (I guess) was asked for a name and password. I gave up.

But anyway, my guess is that you're allocating stuff twice without destroying the first thing, so when you exit it's trying to free() stuff that's already been freed.
Maybe BITMAP *bmp = load_bitmap("mypic.bmp",0) then bmp = load_bitmap("hispic.bmp",0) without a destroy_bitmap(bmp). Or something like that, I don't do C++.

“Throughout history, poverty is the normal condition of man. Advances which permit this norm to be exceeded — here and there, now and then — are the work of an extremely small minority, frequently despised, often condemned, and almost always opposed by all right-thinking people. Whenever this tiny minority is kept from creating, or (as sometimes happens) is driven out of a society, the people then slip back into abject poverty. This is known as "bad luck.”

― Robert A. Heinlein

Iluvatar
Member #7,998
November 2006

I've managed to upload them on a web page. See :
http://pierre.devasselot.free.fr/prog/
The .zip archive brings all files in this folder together

No password needed

Arthur Kalliokoski said:

and (I guess) was asked for a name and password

I see what happened. I was logged when I checked the link. I didn't know a account was required to download atattachment

Arthur Kalliokoski said:

my guess is that you're allocating stuff twice without destroying the first thing

I'll check that. Thanks for the hint.

Il.

Neil Walker
Member #210
April 2000
avatar

Hello,
I haven't checked the code fully, but whenever you work with stuff you create on the heap you should always initialise them to NULL to begin with and when you delete them check they exist,

e.g.

BITMAP* page1=NULL;
...
if(page1) destroy_bitmap(page1);

Also,
I noticed you are destroying bitmaps and making allegro calls in your destructors. Are you sure than these are being called before you exit allegro?

Neil.
MAME Cabinet Blog / AXL LIBRARY (a games framework) / AXL Documentation and Tutorial

wii:0356-1384-6687-2022, kart:3308-4806-6002. XBOX:chucklepie

Iluvatar
Member #7,998
November 2006

Neil Walker said:

you should always initialise them to NULL to begin with

It's done in the contructors

Neil Walker said:

Are you sure than these are being called before you exit allegro

I'm not sure but I suppose so, because I call 'delete item' in the destructor of the 'Moteur' object. I suppose 'moteur' object is deleted at the end of main, before exiting allegro.

Neil Walker said:

when you delete them check they exist

I do it now, but it doesn't change anything.

Il.

piccolo
Member #3,163
January 2003
avatar

your code crash on almost every action.
heres an example of how to make your own menu i took this from my game THe Game in the depot.

[code]
//MenuObject.h
#include <string>
using std::string;

class MenuObject
{
protected:
int x,y,w,h,color;
bool coligion,selceted;
string lable;

public:
BITMAP *bmp;
string Get_lable();
BITMAP* Get_bmp();
int Get_x();
int Get_y();
int Get_w();
int Get_h();
int Get_color();
bool Get_coligion();
bool Get_selceted();
void Set_lable(string);
void Set_bmp(BITMAP*);
void Set_x(int);
void Set_y(int);
void Set_w(int);
void Set_h(int);
void Set_color(int);
void Set_coligion(bool);
void Set_selceted(bool);
void draw();
bool is_collision(MenuObject);
MenuObject();
};

BITMAP* MenuObject::Get_bmp()
{
return bmp ;
}


string MenuObject::Get_lable()
{
return lable;
}
int MenuObject::Get_x()
{
return x;
}
int MenuObject::Get_y()
{
return y;
}
int MenuObject::Get_w()
{
return w;
}
int MenuObject::Get_h()
{
return h;
}
int MenuObject::Get_color()
{
return color;
}
bool MenuObject::Get_coligion()
{
return coligion;
}
bool MenuObject::Get_selceted()
{
return selceted;
}
void MenuObject::Set_bmp(BITMAP* q)
{
bmp = q;
}
void MenuObject::Set_lable(string q)
{
lable = q;
}
void MenuObject::Set_x(int q)
{
x=q;
}
void MenuObject::Set_y(int q)
{
y=q;
}
void MenuObject::Set_w(int q)
{
w=q;
}
void MenuObject::Set_h(int q)
{
h=q;
}
void MenuObject::Set_color(int q)
{
color=q;
}
void MenuObject::Set_coligion(bool q)
{
coligion=q;
}
void MenuObject::Set_selceted(bool q)
{
selceted=q;
}
bool MenuObject::is_collision( MenuObject b)
{
if ((x > b.x + b.w -1) || // is a on the right side
(y > b.y + b.h -1) || // is a under
(b.x > x + w -1) || // is b on the right side
(b.y > y + h -1)) // is b under
{
// this means that there is no collision
return 0; // means no colide
}

return 1; // means colide
}



MenuObject::MenuObject()
{
x=0;
y=0;
w=100;
h=100;
color=makecol(255,255,55);
coligion=selceted=false;
lable="no lable";
bmp = screen;


}
void MenuObject::draw()
{
}



[/code]

[code]


//Textbox.h

#include "MenuObject.h"

class Textbox :public MenuObject
{
private:

string text; // an empty string for editting
string::iterator iter ;// string iterator
int scolor;
int ecolor;
int tra;
int caret ; // tracks the text caret
bool insert ; // true of should text be inserted




public:
int Get_scolor();
int Get_ecolor();
void Set_scolor(int);

void Set_ecolor(int);
void Set_defaltText(string);
Textbox();
Textbox(string);

~Textbox()
{

}
string draw(BITMAP *bmp);

};

Textbox::Textbox()
{

selceted = false;
text="";// an empty string for editting
iter = text.begin(); // string iterator
x=mouse_x;
y=mouse_y;
caret = x-87;// tracks the text caret
w=100;
h=25;
insert = true; // true of should text be inserted
tra=text.length();
scolor = makecol(0,255,0);
ecolor = makecol(255,0,0);
}

Textbox::Textbox(string t)
{

selceted = false;
text= t;
iter = text.end(); // string iterator
x=mouse_x;
y=mouse_y;
caret = x-87;// tracks the text caret
w=100;
h=25;
insert = true; // true of should text be inserted
tra=text.length();
scolor = makecol(0,255,0);
ecolor = makecol(255,0,0);
}
int Textbox::Get_scolor()
{
return scolor;
}
int Textbox::Get_ecolor()
{
return ecolor;
}

void Textbox::Set_scolor(int q)
{
scolor = q;
}
void Textbox::Set_ecolor(int q)
{
ecolor=q;
}


void Textbox::Set_defaltText(string t)
{
text = t;
tra=text.length();
iter = text.end();
}








string Textbox::draw(BITMAP *bmp)
{
if( selceted == true)
{
while(keypressed())
{
int newkey = readkey();
char ASCII = newkey & 0xff;
char scancode = newkey >> 8;

// a character key was pressed; add it to the string
if(ASCII >= 32 && ASCII <= 126)
{
// add the new char, inserting or replacing as need be
if(insert || iter == text.end())
iter = text.insert(iter, ASCII);
else
text.replace(caret, 1, 1, ASCII);

// increment both the caret and the iterator
caret++;
iter++;
}
// some other, "special" key was pressed; handle it here
else
switch(scancode)
{
case KEY_DEL:
if(iter != text.end()) iter = text.erase(iter);
break;

case KEY_BACKSPACE:
if(iter != text.begin())
{
caret--;
iter--;
iter = text.erase(iter);
}
break;

case KEY_RIGHT:
if(iter != text.end()) caret++, iter++;
break;

case KEY_LEFT:
if(iter != text.begin()) caret--, iter--;
break;

case KEY_INSERT:
if(insert) insert = 0; else insert = 1;
break;

case KEY_ENTER:
if(iter != text.begin())
{
//this give runtime error
if(computerId==severId)
{
//need to put in life contter
//serverdiolog = text;
//outboxbuffer +="9999|" + NumberToString(computerId) + "|003|" + NumberToString(computerId) + "," + text +"`~";

}
else
{
//need somthing for sending msg to serten clients
//outboxbuffer +="0|" + NumberToString(computerId) + "|003|" + NumberToString(computerId) + "," + text +"`~";
}
//tra=text.length();
//caret-=(tra);
//iter-=(tra);
//text.erase(0,tra+1);

}
break;
default:

break;
}
}
// output some stats using Allegro's printf functions
//textprintf(bmp, font, x, 20, makecol(255,255,255), "length: %d", text.length());
//textprintf(bmp, font, x, 30, makecol(255,255,255), "capacity: %d", text.capacity());
//textprintf(bmp, font, x, 40, makecol(255,255,255), "empty`: %d", text.empty());
//if(insert)
//textout(bmp, font, "Inserting", x, 50, makecol(255,255,255));
//else
//textout(bmp, font, "Replacing", x, 50, makecol(255,255,255));
// draw the caret
vline(bmp, caret * 8, 8, 18, makecol(255,255,255));
}
// clear bmp
//clear(buffer);








// output the string to the bmp
textout(bmp,font,Get_lable().c_str(),Get_x() ,Get_y()-10,makecol(255,255,255));
textout(bmp, font, text.c_str(), x+10, y+10, makecol(255,255,255));
drawRectangle(bmp,Get_x(), Get_y(), Get_w(), Get_h(), Get_color(), 2, Get_color());
return text;
}



[/code]

[code]

#include "Textbox.h"
//Button.h

class Button : public MenuObject
{
private:
int state;
int scolor;
int ecolor;
public:
int Get_scolor();
int Get_ecolor();
int Get_state();
void Set_scolor(int);
void Set_ecolor(int);
void Set_state(int);
Button();
void draw(BITMAP *bmp);
};
Button::Button()
{
x = mouse_x;
y = mouse_y;
w = 100;
h = 25;
state = 0;
scolor = makecol(0,255,0);
ecolor = makecol(255,0,0);

}
int Button::Get_state()
{
return state;
}
int Button::Get_scolor()
{
return scolor;
}
int Button::Get_ecolor()
{
return ecolor;
}
void Button::Set_state(int q)
{
state = q;
}
void Button::Set_scolor(int q)
{
scolor = q;
}
void Button::Set_ecolor(int q)
{
ecolor=q;
}
void Button::draw(BITMAP *bmp)
{


if(state == 0)
{
Set_color(scolor);
}
else if (state == 1)
{
//textout(bmp,font,Get_lable().c_str(),100 ,100,makecol(255,255,255));
Set_color(ecolor);
}

drawRectangle(bmp,Get_x(), Get_y(), Get_w(), Get_h(), Get_color(), 2, Get_color());
textout(bmp,font,Get_lable().c_str(),Get_x() +10,Get_y()+10,makecol(255,255,255));
}



[/code]


[code]

//Mouse.h
#include "Button.h"

class Mouse: public MenuObject
{
private:

public:
Mouse();


bool is_doubleclick();

void draw(BITMAP *bmp);
};
Mouse::Mouse()
{
Set_x(mouse_x);
Set_y(mouse_y);
Set_w(10);
Set_h(10);
}
void Mouse::draw(BITMAP *bmp)
{
show_mouse(bmp);
Set_x( mouse_x);
Set_y( mouse_y);
drawRectangle(bmp,Get_x(), Get_y(), Get_w(), Get_h(), Get_color(), 0, Get_color());
scare_mouse();

}
//hummmm i think this crashes
bool Mouse::is_doubleclick()//we can even put the sleep valus as ints in the fuction header for more flex
{
if (mouse_b & 1)
{
Sleep(50);
if (!(mouse_b & 1))
{
Sleep(50);
if (mouse_b & 1)
{

return true;

}
return false;
}
return false;
}
return false;
}



[/code]

This is the login menu used in my client
should work find for you just get rid of the functions that get called by the objects.
[code]
#include "Menu.h"
Menu login;

int draw_login(BITMAP* bmp)
{

login.buttons[0].Set_lable( " Logon");
login.buttons[0].Set_x(login.Get_x()+50);
login.buttons[0].Set_y(login.Get_y()+40);
login.buttons[0].Set_w(100);
login.buttons[0].Set_h(25);
login.buttons[1].Set_lable( "Make New");
login.buttons[1].Set_x(login.Get_x()+100);
login.buttons[1].Set_y(login.Get_y()+130);
login.buttons[1].Set_w(100);
login.buttons[1].Set_h(25);

login.buttons[2].Set_lable( " Exit");
login.buttons[2].Set_x(login.Get_x()+100);
login.buttons[2].Set_y(login.Get_y()+170);
login.buttons[2].Set_w(100);
login.buttons[2].Set_h(25);

login.textboxs[0].Set_lable( "Enter Uesrname");
login.textboxs[0].Set_x(login.Get_x()+160);
login.textboxs[0].Set_y(login.Get_y()+20);
login.textboxs[0].Set_w(100);
login.textboxs[0].Set_h(25);

login.textboxs[1].Set_lable( "Enter PassWord");
login.textboxs[1].Set_x(login.Get_x()+160);
login.textboxs[1].Set_y(login.Get_y()+60);
login.textboxs[1].Set_w(100);
login.textboxs[1].Set_h(25);


login.textboxs[2].Set_lable( "Server IP");
login.textboxs[2].Set_x(login.Get_x()+18);
login.textboxs[2].Set_y(login.Get_y()+92);
login.textboxs[2].Set_w(185);
login.textboxs[2].Set_h(25);
login.textboxs[2].Set_defaltText(serverIP);



login.draw(bmp);

login.buttons[0].draw(bmp);
login.buttons[1].draw(bmp);
login.buttons[2].draw(bmp);

username = login.textboxs[0].draw(bmp); //returns username
password = login.textboxs[1].draw(bmp); //returns password
serverIP = login.textboxs[2].draw(bmp); //returns serverIP

if (!(mouse_b & 1))
{
login.mx = mouse_x;
login.my = mouse_y;
}
login.mouse[0].draw(bmp);
if (mouse_b & 1)
//if (is_doubleclick())
{
if(login.is_collision( login.mouse[0]))
{
if(!login.buttons[0].is_collision( login.mouse[0]))
{
if(!login.buttons[1].is_collision( login.mouse[0]))
{
if(!login.textboxs[0].is_collision( login.mouse[0]))
{
if(!login.textboxs[1].is_collision( login.mouse[0]))
{
if(!login.textboxs[2].is_collision( login.mouse[0]))
{

//login.Set_x( mouse_x );
//login.Set_y( mouse_y );
login.mov=mouse_x -login.mx;
login.mov2=mouse_y - login.my;
login.mx = mouse_x;
login.my = mouse_y;

login.Set_x( login.Get_x()+login.mov);
login.Set_y( login.Get_y()+login.mov2);

login.mov = 0;
login.mov2 = 0;
//mouse_x = login.mov + login.Get_x();
//mouse_y = login.mov2 + login.Get_y();
}
}
}
}
}
}

if(login.buttons[0].is_collision( login.mouse[0]))
{
login.buttons[0].Set_state(1);
//do this buttons stuff login
//sub menu get username and password
//need to give chances to enter that mean we need sever conection here
//contiual on to game

return 1;
}
else
{
login.buttons[0].Set_state(0);
}
if(login.buttons[1].is_collision( login.mouse[0]))
{
login.buttons[1].Set_state(1);
//do this buttons stuff new acount

}
else
{
login.buttons[1].Set_state(0);

}

if(login.buttons[2].is_collision( login.mouse[0]))
{
login.buttons[2].Set_state(1);
//do this buttons stuff exit
return -1;//are you done drawing
}
else
{
login.buttons[2].Set_state(0);
}

if(login.textboxs[0].is_collision( login.mouse[0]))
{

login.textboxs[0].Set_selceted(true);
login.textboxs[1].Set_selceted(false);
login.textboxs[2].Set_selceted(false);
//username text box has keybord

}
if(login.textboxs[1].is_collision( login.mouse[0]))
{

login.textboxs[0].Set_selceted(false);
login.textboxs[1].Set_selceted(true);
login.textboxs[2].Set_selceted(false);
//passWord text box has keybord

}
if(login.textboxs[2].is_collision( login.mouse[0]))
{
login.textboxs[0].Set_selceted(false);
login.textboxs[1].Set_selceted(false);
login.textboxs[2].Set_selceted(true);
//passWord text box has keybord

}
}
return 0; //are you done drawing
}



[/code]

wow
-------------------------------
i am who you are not am i

Iluvatar
Member #7,998
November 2006

Finally, my menu works well. I didn't have enough control structures to check if pointers were well destroyed. For thoses who might want to have a menu like mine, I release source code for it.

It dispays a first window 300x400 with a few options, highlighted when draggong mouse on them, then when selecting 'nouveau', it goes to another window 800x600. When whe click in that window, we go back to the menu. It doesn't go anywhere if we click anywhere in the menu window except on options.

You cad download source code at this adress :
http://pierre.devasselot.free.fr/prog
no login, no password

You can use it as you want.

Il.

Go to: