Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Crash on al_get_time()

This thread is locked; no one can reply to it. rss feed Print
Crash on al_get_time()
Matias Persson
Member #15,093
May 2013

Title says it all.
I am simply trying to keep track of time

double startTime = al_get_time(); <-- Crash because al_get_time() returns -6.0120304019-18e etc.
(This is in my IntroState constructor)

in my timed logic, though it doesn't really has anything to say as it never reaches this point.
if (al_get_time() - startTime >= 5.0) {
nextState = STATE_MENU;
}

Never had this issue before, and this very same program, that hasn't been changed since actually worked yesterday.
Been looking for hours for a solution, can't find one..
I am so confused ??? ??? ???

Edgar Reynaldo
Member #8,592
May 2007
avatar

I'm guessing you have a global IntroState object? Is that correct? If so, al_init won't have been called before calling al_get_time and it will crash. That's probably why you're getting the crazy return value for the time.

Matias Persson
Member #15,093
May 2013

No I don't use globals, been trying for days now, still an error.
Still looking for solution.

Edgar Reynaldo
Member #8,592
May 2007
avatar

Okay, but are you sure you're initializing allegro before you create your IntroState object?

Things like that just shouldn't happen unless you're calling allegro functions before allegro_init.

My other guess is that you updated allegro and you're using a different version of the allegro dll that is no longer compatible with your current allegro headers. It could cause problems like that. Ie. you updated your headers, but not your dlls. That could cause a runtime crash.

Otherwise, you're gonna have to show more code. Show main at least.

Matias Persson
Member #15,093
May 2013

I initialize everything before trying to use any allegro functions.
I don't use globals.
Etc.. I follow everything that must be done.

Here's code.

#SelectExpand
1#include <iostream> 2#include <memory> 3#include <allegro5/allegro.h> 4#include <allegro5/allegro_font.h> 5#include <allegro5/allegro_ttf.h> 6 7#include "GameState.h" 8#include "IntroState.h" 9#include "MenuState.h" 10 11int Initialize(ALLEGRO_DISPLAY *&display, ALLEGRO_EVENT_QUEUE *&event_queue, ALLEGRO_TIMER *&timer); 12void setNextState(int newState); 13void ChangeState(); 14int Cleanup(ALLEGRO_DISPLAY *&display, ALLEGRO_EVENT_QUEUE *&event_queue, ALLEGRO_TIMER *&timer); 15 16int stateID = STATE_INTRO; 17int nextState = STATE_NULL; 18std::unique_ptr<CGameState> currentState; 19 20int main() { 21 22 ALLEGRO_DISPLAY *display; 23 ALLEGRO_EVENT_QUEUE *event_queue; 24 ALLEGRO_TIMER *timer; 25 ALLEGRO_EVENT ev; 26 27 Initialize(display, event_queue, timer); 28 29 al_start_timer(timer); 30 31 currentState = std::make_unique<CIntroState>(); 32 33 while (stateID != STATE_EXIT) { 34 while (!al_is_event_queue_empty(event_queue)) { 35 al_wait_for_event(event_queue, &ev); 36 //Check input here 37 //Keyboard keyboard; 38 //checkInput(keyboard, ev); 39 40 if (ev.type == ALLEGRO_EVENT_TIMER) 41 { 42 //Do timed logic. 43 currentState->TimedLogic(nextState); 44 } 45 else if (ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE) { 46 //Set to exit state, if user closes the program. 47 setNextState(STATE_EXIT); 48 } 49 //Do untimed logic. 50 currentState->UntimedLogic(); 51 } 52 53 currentState->Render(); 54 55 //Change state if needed 56 ChangeState(); 57 58 al_rest(0.001); 59 } 60 61 Cleanup(display, event_queue, timer); 62} 63 64int Initialize(ALLEGRO_DISPLAY *&display, ALLEGRO_EVENT_QUEUE *&event_queue, ALLEGRO_TIMER *&timer) { 65 if (!al_init()) { 66 return -1; 67 } 68 69 display = al_create_display(640, 480); 70 if (!display) { 71 al_destroy_display(display); 72 return -1; 73 } 74 75 event_queue = al_create_event_queue(); 76 if (!event_queue) { 77 al_destroy_event_queue(event_queue); 78 return -1; 79 } 80 81 timer = al_create_timer(1.0 / 60.0); 82 if (!timer) { 83 al_destroy_timer(timer); 84 return -1; 85 } 86 87 al_install_keyboard(); 88 al_install_mouse(); 89 al_init_font_addon(); 90 al_init_ttf_addon(); 91 92 al_register_event_source(event_queue, al_get_display_event_source(display)); 93 al_register_event_source(event_queue, al_get_timer_event_source(timer)); 94 al_register_event_source(event_queue, al_get_keyboard_event_source()); 95 al_register_event_source(event_queue, al_get_mouse_event_source()); 96 97 return 1; 98} 99 100void setNextState(int newState) { 101 if (nextState != STATE_EXIT) 102 nextState = newState; 103} 104 105void ChangeState() { 106 if (nextState != STATE_NULL) { 107 switch (nextState) { 108 case STATE_INTRO: 109 currentState = std::make_unique<CIntroState>(); 110 break; 111 case STATE_MENU: 112 currentState = std::make_unique<CMenuState>(); 113 break; 114 case STATE_PLAY: 115 break; 116 } 117 118 stateID = nextState; 119 120 nextState = STATE_NULL; 121 } 122} 123 124int Cleanup(ALLEGRO_DISPLAY *&display, ALLEGRO_EVENT_QUEUE *&event_queue, ALLEGRO_TIMER *&timer) { 125 al_destroy_display(display); 126 al_destroy_timer(timer); 127 al_destroy_event_queue(event_queue); 128 return 0; 129}

GameState.h

#SelectExpand
1#pragma once 2 3//#include "Keyboard.h" 4 5enum GameStates {STATE_NULL, STATE_INTRO, STATE_MENU, STATE_PLAY, STATE_EXIT}; 6 7class CGameState 8{ 9public: 10 CGameState(); 11 virtual ~CGameState() = 0; 12 13 virtual void TimedLogic(int &nextState) = 0; 14 virtual void UntimedLogic() = 0; 15 virtual void Render() = 0; 16};

IntroState.h

#SelectExpand
1#pragma once 2 3#include "GameState.h" 4 5#include <iostream> 6#include <allegro5/allegro.h> 7#include <allegro5/allegro_font.h> 8#include <allegro5/allegro_ttf.h> 9 10class CIntroState : 11 public CGameState 12{ 13public: 14 CIntroState(); 15 ~CIntroState(); 16 17 void TimedLogic(int &nextState); 18 void UntimedLogic(); 19 void Render(); 20 21private: 22 double startTime; 23 ALLEGRO_FONT *arial; 24};

Peter Hull
Member #1,136
March 2001

Seems like you've thought of everything! Questions:

  • Is this Windows?

  • Which version of Allegro?

  • Can you post the code where you're calling al_get_time() ?

As an aside, where you have

display = al_create_display(640, 480); 
if (!display) { 
 al_destroy_display(display); 
 return -1; 
}

this doesn't make sense; if al_create_display returns NULL, it's failed and there is nothing to call al_destroy_display on.

Bruce Pascoe
Member #15,931
April 2015
avatar

If al_get_time() is returning insane values, that's usually because you've called it before initializing Allegro. That doesn't appear to be the case here though, so it's definitely weird.

I see global variables though. ;)

SiegeLord
Member #7,827
October 2006
avatar

My other guess is that you updated allegro and you're using a different version of the allegro dll that is no longer compatible with your current allegro headers. It could cause problems like that. Ie. you updated your headers, but not your dlls. That could cause a runtime crash.

That's a possibility. You check for al_init succeeding, but you don't check for Initialize succeeding. al_init might fail, and and you might proceed anyway and get all sorts of crashes. Weird that al_start_timer doesn't crash though :P.

"For in much wisdom is much grief: and he that increases knowledge increases sorrow."-Ecclesiastes 1:18
[SiegeLord's Abode][Codes]:[DAllegro5]:[RustAllegro]

Edgar Reynaldo
Member #8,592
May 2007
avatar

From my experience, when al_init fails, it's usually because of a version mismatch between the headers compiled against and the dll in use. Allegro does a version check on start up inside al_init that will fail if the runtime is different from the headers used.

Matias Persson
Member #15,093
May 2013

Sorry for the late reply, been busy lately.
Well, actually there are no globals, there are scope variables, but they don't interfer with anything else.

Peter Hull:
Yes, windows.
Allegro 5.0.10, I also use 5.0.10 dlls, no mismatch in versions.
I have posted the code where I am calling al_get_time() in IntroState class.
Nevermind that, I didn't actually.. Here's the code:

#SelectExpand
1#include "IntroState.h" 2 3CIntroState::CIntroState() 4{ 5 std::cout << "Entered Intro State" << std::endl; 6 startTime = al_get_time(); 7 arial = al_load_font("arial.ttf", 12, 0); 8 if (!arial) { 9 al_destroy_font(arial); 10 exit(-1); 11 } 12} 13 14CIntroState::~CIntroState() { 15 std::cout << "Leaving Intro State" << std::endl; 16} 17 18void CIntroState::TimedLogic(int &nextState) { 19 if (al_get_time() - startTime >= 5.0) { 20 nextState = STATE_MENU; 21 } 22}

On your aside text, do you propose I should say:

if(!display = al_create_display(640,480)) {
return 0;
}

instead?

Still having issues with this, very weird.. As I said, it works on my desktop computer.

Bruce Pascoe
Member #15,931
April 2015
avatar

Looking at that code and what you posted above, you're definitely calling al_init() before al_get_time(), so not sure why you're getting insane values. The only thing I can think of is that initialization is failing behind your back (as mentioned above, you aren't checking the return value of Initialize() ).

Edgar Reynaldo
Member #8,592
May 2007
avatar

Neil Roy
Member #2,229
April 2002
avatar

if(!display = al_create_display(640,480)) {
   return 0;
}

I would just change your original code you posted for this to...

if(display == NULL) {
   return -1;
}

You're also making the same mistake with your font loading...

arial = al_load_font("arial.ttf", 12, 0);
if (!arial) {
   al_destroy_font(arial);
   exit(-1);
}

You're trying to destroy the arial font, but that is only needed if you successfully loading it in the first place. If loading fails, than there is nothing to destroy, no need to call that. Just use

arial = al_load_font("arial.ttf", 12, 0);
if (arial == NULL) {
   exit(-1);
}

As for your main problem, according to the online docs (https://www.allegro.cc/manual/5/al_get_time): "The return value is undefined if Allegro is uninitialised."

Looking at your code, I see a problem right away... what is this...

int Initialize(ALLEGRO_DISPLAY *&display, ALLEGRO_EVENT_QUEUE *&event_queue, ALLEGRO_TIMER *&timer);

You have *&display? ? You only need &display in C++ or *display but not both.

So the problem is that Allegro is not being initialized properly.

So your function prototype should be...

int Initialize(ALLEGRO_DISPLAY &display, ALLEGRO_EVENT_QUEUE &event_queue, ALLEGRO_TIMER &timer);

and in main() you should have...

ALLEGRO_DISPLAY *display;
ALLEGRO_EVENT_QUEUE *event_queue;
ALLEGRO_TIMER *timer;
ALLEGRO_EVENT ev;

Initialize(display, event_queue, timer);

Bruce Pascoe
Member #15,931
April 2015
avatar

No, *& is correct - he's passing the ALLEGRO_DISPLAY* by reference. I'm pretty sure ALLEGRO_DISPLAY& won't compile because that's an opaque type (i.e. Allegro doesn't expose the actual struct contents so the compiler doesn't know how large it is).

Neil Roy
Member #2,229
April 2002
avatar

He's passing a pointer. So the function should take a pointer or a reference, but not both. Never used both together before and honestly, I am surprised it compiled like that.

Bruce Pascoe
Member #15,931
April 2015
avatar

He's passing a reference to the pointer, that's correct. al_create_display() returns ALLEGRO_DISPLAY*, so you have to have a reference to the pointer type if you want to store it.

It might clarify things to say that, if this were C where pass-by-reference isn't allowed, for Initialize() to work the way it's set up now, it would have to take an ALLEGRO_DISPLAY** (a pointer to the pointer).

Peter Hull
Member #1,136
March 2001

As I said, it works on my desktop computer.

Dunno, did you say that? Do you mean the exact same binary copied from one computer to the other works on one and not the other? Or are you compiling the same source code on each one?

As has been mentioned al_init failing (somehow) seems likely - another possibility is that al_get_time is OK but the stored value (CIntroState::startTime) is being corrupted subsequently. If you get your debugger on the place where it's being set, is it always garbage?

Matias Persson
Member #15,093
May 2013

Exact same source code, not binary.
But that doesn't really matter as I have set it up correctly, and as I said, it used to work before too. Never had any problems with this sort of code on my laptop before.
Anyways, matter is closed, will just not program on my laptop :)

Go to: