Closed mspraggs closed 9 years ago
I think there might be a memory leak as well though. I fell asleep with it running, and woke up to a segfault… I'll try to run it while I'm awake and get some better debug info.
Here is the bug report from the out of range exception:
Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0 libsystem_kernel.dylib 0x00007fff8b620ce2 pthread_kill + 10
1 libsystem_c.dylib 0x00007fff9016f7d2 pthread_kill + 95
2 libsystem_c.dylib 0x00007fff90160a7a abort + 143
3 libc++abi.dylib 0x00007fff8db0b7bc abort_message + 214
4 libc++abi.dylib 0x00007fff8db08fcf default_terminate() + 28
5 libobjc.A.dylib 0x00007fff92ada1cd _objc_terminate + 114
6 libc++abi.dylib 0x00007fff8db09001 safe_handler_caller(void (*)()) + 11
7 libc++abi.dylib 0x00007fff8db0905c std::terminate() + 16
8 libc++abi.dylib 0x00007fff8db0a152 cxa_throw + 114
9 libc++.1.dylib 0x00007fff8f4acd6b std::1::vector_base_common
Ah I get this now. I ran the game under gdb (the gnu debugger) and inspected the CURRENT_ROOM when the exception is thrown. The line it's failing on is this:
return CURRENT_ROOM.getProps()->at(0).code() == 'y';
getProps returns a pointer to the props vector, and this has size zero, hence calling at(0) on the vector raises an exception. This is slightly odd as there's a beforehand while loop that should ensure that should ensure that the props are there.
while(!INPUT.quit() && !(CURRENT_ROOM.getProps()->size() < 2 && WINDOW.faded())) {
INPUT.scan();
World::instance().update();
you_.update();
if(CURRENT_ROOM.getProps()->size() < 2)
WINDOW.fadeOut();
World::instance().draw();
you_.draw();
WINDOW.print("Quit", Vector(0.2f, 0.6f), WHITE);
WINDOW.print("Retry", Vector(0.7f, 0.6f), WHITE);
WINDOW.flush();
}
return CURRENT_ROOM.getProps()->at(0).code() == 'y';
I may be wrong, but doesn't the condition on the while-loop at the top mean that if WINDOW.faded() returns false, the function returns even if props is zero-length? (This is game::outdo, btw)
Edit: Nope, that's nonsense. I read the && as an || for some reason...
Woo! I fixed it.
A couple of problems:
We were calling:
while(!INPUT.quit() && !(you_.dead() && WINDOW.faded()) && !Game::instance().have_won())
to leave the loop in Game::run(), which was checking for fadeout on death, but not on winning. Since we have a few different things checking _hasFaded(), that caused an infinite room load loop if outro returned true.
After playing the ten levels required to win, then clicking the retry balloon, an exception is thrown because a vector is being indexed out of its bounds. Console output:
You won! Loaded 1 guns Info: Loading room file david levels/Lv6.txt terminate called after throwing an instance of 'std::out_of_range' what(): vector::_M_range_check [1] 3631 abort (core dumped) ./game