我试图用C ++和Allegro 4.2.3编写我的第一个简单游戏,但是当我改变游戏状态时,我有时会发生崩溃。当状态开始时,它使用“新”状态。运营商制作它,然后使用'删除'在切换到下一个之前。不过,我不确定我是否完全理解使用new和delete运算符!这是一个代码选择:
enum //Game state
{
TITLE_SCREEN, CUTSCENE_1
};
int main(void)
{
const int screenwidth = 800;
const int screenheight = 600;
bool quit = false;
int state = TITLE_SCREEN;
int oldstate = -1;
int oldoldstate;
init(screenwidth, screenheight);
install_int(counter, (1000/FPS));
TitleState *Title;
Cutscene *Scene1;
srand (time(NULL));
while (!quit)
{
while(tick == 0)
{
rest(1);
}
while(tick > 0)
{
oldoldstate = oldstate;
oldstate = state;
switch(state)
{
case TITLE_SCREEN:
//If the last state is different to this one, create the state
if(oldoldstate != TITLE_SCREEN)
{
Title = new TitleState();
}
//Run the program in the state
Title->Play();
//Check the state to see if it has changed
state = Title->CheckState();
//If the state has changed, delete the current state
if(oldstate != state)
{
delete Title;
}
break;
case CUTSCENE_1:
if(oldoldstate != CUTSCENE_1)
{
Scene1 = new Cutscene(); //SOMETIMES CRASHES BEFORE HERE
}
Scene1->Play();
state = Scene1->CheckState();
if(oldstate != state)
{
delete Scene1;
}
break;
case EXIT:
quit = true;
break;
default:
allegro_message("Game state not found!");
exit(-1);
}
int oldtick = tick;
tick--;
if(oldtick <= tick)
break;
}
}
deinit();
return 0;
}
当程序崩溃时,VS2010会打开thread.c来显示错误的位置:
static void _callthreadstart(void)
{
_ptiddata ptd; /* pointer to thread's _tiddata struct */
/* must always exist at this point */
ptd = _getptd();
/*
* Guard call to user code with a _try - _except statement to
* implement runtime errors and signal support
*/
__try
{
( (void(__CLRCALL_OR_CDECL *)(void *))(((_ptiddata)ptd)->_initaddr) )
( ((_ptiddata)ptd)->_initarg ); //ERROR HERE (Next statement to be executed)
_endthread();
}
__except ( _XcptFilter(GetExceptionCode(), GetExceptionInformation()) )
{
/*
* Should never reach here
*/
_exit( GetExceptionCode() );
} /* end of _try - _except */
}
我非常感谢任何帮助,因为我根本不确定问题是什么。
答案 0 :(得分:1)
感谢您的帮助和建议,他们很有趣,也很有用!但是,我认为我的问题的解决方案是使用更新版本的Allegro库 - 我被告知使用4.2.3,但据我所知,移至4.4.2已经消除了这个问题!
答案 1 :(得分:0)
新的是从堆中分配内存,而删除是为了释放它。 您不能删除(释放)两次相同的内存。您可以阅读一些关于new / delete的教程。
虽然我没有查看你的代码,但是你可以做的事情很少, 1)在gdb中运行你的代码(为了获得崩溃的堆栈跟踪,它会告诉大部分事情)。 2)如果是因为new / delete,那么可能是因为double free,还有其他原因导致new / delete失败。 3)您可以保持调用new / delete的次数,您可以覆盖new / delete并编写自己的新/删除例程。 4)如果您无法执行上述任何操作,则只需编写printf语句即可了解失败的位置。 printf可能并不总是可靠的,你可以使用fflush()。
答案 2 :(得分:0)
这只是程序代码的一小部分,很难说它可能是错误的。
这是因为C ++具有“未定义行为”的概念,当你做错了(例如删除相同的对象两次)时,你不能依赖于立即引发错误这一事实,但会发生的是其他东西,甚至是无关的,可能会在以后表现得很奇怪(甚至以后会执行数百万条指令)。
该语言的一个基本假设是程序员不会做这种错误(如图!)。
你完全有可能在代码的其他部分犯了一个错误,你看到delete
调用中的错误,然而这只是所发生事件的“受害者”,而不是问题所在的点
有一些通用规则可以帮助防止分配/释放错误(比如使用标准容器而不是裸指针,并遵循“三巨头”的规则)。
每次在C ++程序中编写指令时,都应该考虑很多,因为如果你让一个逻辑错误很难在以后删除它。在语言层面不存在“未定义行为”的语言中,这不是一个问题。