Works in Debug... Not in Release

Jul 8, 2012 at 4:39am
As the title suggests, I have run across an issue of something working in the Debug run when it runs with the IDE, but if I run the release version without the IDE, it fails.

I have a GUI (main menu) that leads to the rest of the program when a button is clicked. It'll run until I click that button.

I have narrowed it down to this line of code, but I'm not sure why it won't run it.

parent->game_state = ClassA::GameState::in_game;
Game_state is an enumerator that is inside of ClassA. This line of code is being called from a child of ClassA.

I feel like the problem lies in having to include the files for the classes inside of each other, but I couldn't think of another way to give the child class access to the enumerator.

Any thoughts on the matter?
Jul 8, 2012 at 6:32am
We'll need more code to see what the issue is. Post the function that runs when you click the button at least.
Jul 8, 2012 at 6:57am
Usually the "works in debug but not release" problem comes down to some kind of uninitialized variable issue. This is because all variables are automatically initialized to zero in debug mode and this could mask a problem where a garbage value is used.
Jul 8, 2012 at 3:36pm
When the button is clicked it runs this function. It's very short. Basically, engine is a pointer inside of ClassA. The main menu is also inside of ClassA, so I passed ClassA to the main menu, so I could change the state of the program from on_main_menu to in_game.
1
2
3
4
void StartMenu::NewGameClicked() {
	parent->game_state = ClassA::GameState::in_game;
	parent->InitializeEngine();
}

The only thing InitializeEngine() does is:
1
2
3
void ClassA::InitializeEngine() {
	engine = new Engine;
}


@shacktar: The variable, game_state, the one causing the problem, is set to a value in the constructor of the main class.
Jul 8, 2012 at 4:11pm
Is parent a valid pointer? What about the StartMenu object, is that valid? Sometimes calling a member function on an invalid object pointer will cause the crash to happen inside of the function once it uses member variables.
Jul 8, 2012 at 5:53pm
I'm pretty sure it is, can't be too sure though.
class_a.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include "start_menu.h"

class StartMenu;

class ClassA
{
public:
    enum GameState { on_main_menu = 0, in_game } game_state;

    void InitializeEngine();

private:
    Engine *engine;
    StartMenu *start_menu;
};


start_menu.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include "class_a.h"

class ClassA;

class StartMenu
{
public:
    StartMenu(ClassA* _parent, sf::RenderWindow* _window); // parent = _parent; <--- Inside constructor

private:
    void NewGameClicked();

    ClassA* parent;
};


I left a lot out of these class declarations so as to make them shorter on you guys. I included what it related to the pointers.

EDIT: I forgot this.
1
2
3
4
5
ClassA::ClassA() {
	game_state = on_main_menu;
	window = new sf::RenderWindow(sf::VideoMode(1280, 720), "The Reverend");
	main_menu = new StartMenu(this, window);
}
Last edited on Jul 8, 2012 at 6:06pm
Jul 9, 2012 at 1:13am
You have a circular include there, start_menu.h includes class_a.h which includes start_menu.h which includes class_a.h and so on. Not sure why that compiles...

What does the Engine constructor look like? All the code here looks fine, provided nothing else gets run in between.
Jul 9, 2012 at 1:18am
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
Engine::Engine() {
	running = true;
	take_input = true;

	std::ifstream map_list("MapList.txt");
	for (unsigned i = 0; map_list.good(); ++i) {
		string temp;
		getline(map_list, temp);
		try {
			maps.push_back(new Map(temp)); }
		catch (std::bad_alloc) {
			std::cout << "std::bad_alloc | Failed to allocate memory to create map in engine." << std::endl; }
	}
	map_list.close();

	current_map = 0;
	tile_dimensions = sf::Vector2i((int)maps[current_map]->GetTileWidth(), (int)maps[current_map]->GetTileHeight());
	try {
		connor = new Connor("Characters/Connor"); }
	catch (std::bad_alloc) {
		std::cout << "std::bad_alloc | Failed to allocate memory to create Connor in engine." << std::endl; }
	connor->SetGlobalCoords(4 * tile_dimensions.x, 4 * tile_dimensions.y);
}


Here is the Engine constructor. It's worked forever, so I don't know if anything would be wrong here.

However, back when I programmed on Code::Blocks (another IDE, if you didn't know), I first discovered circular includes and that IDE wouldn't compile with them. MS VS2010 does however, so I used it. I can't think of another way to get a pointer to the parent, other than what I did. :/
Is there another way to do that? Maybe without circular includes?
Jul 9, 2012 at 9:42am
If you ran your code using a debugger (i.e. the release build, with debugging symbols added, under a debugger - not the debug build, which is clearly different) it would tell you the exact line causing the problem and you would be able to interrogate the variables to find the culprit.
Jul 9, 2012 at 4:37pm
The program works perfectly fine when wrapped with a debugger even in Release mode. :/

Only when I run the *.exe file from the directly file-path does it fail.

I do in fact know which line it is though.
I have narrowed it down to this line of code, but I'm not sure why it won't run it.

parent->game_state = ClassA::GameState::in_game;

There is a circular include in the program, but I'm not sure if THAT is what is causing this.
Jul 9, 2012 at 10:18pm
If you only need a pointer or a reference, then all you have to do is forward declare the class ( class Parent; ) then just include the header from the source file of the class that needs it.

When you're loading the maps for the engine, change the loop to:
1
2
3
4
while (getline(map_list, temp))
{
    //stuff
}

That way you don't have the one extra loop at the end, or the extra overhead of the for loop where it isn't needed. This *might* be the cause of the crash, but other than that I really have no idea what else could be causing it.
Topic archived. No new replies allowed.