Unhandled Exception

Hello, I’ve been trying to make a complete level by populating tiles. However, I face this error that I can’t figure out:

There are quite a few files so here’s github link

Thank you for your attention.

Access violation reading location 0x0000000000000000.

This sounds like you’re trying to dereference a null pointer.


You only list 9 rows when initializing tile_map.

const char* tile_map[10] = {
"                            ",
" XX    XXX            XX    ",
" XX                         ",
" XXXX          XX        XX ",
" XXXX        XX             ",
" XX    X  XXXX    XX   XX   ",
"       X  XXXX    XX   XXX  ",
"     XXX  XXXXXX  XX   XXXX ",
"XXXXXXXX  XXXXXX  XX   XXXX ",
};

This means that tile_map[9] will be a null pointer.

1 Like

Oh, my bad, thank you. Also, when I try to create a extern vector to store all of my tiles like so

extern vector < Tile* > group_of_tiles;

I have included <vector> and am using namespace std;

it throws me this error:

Looks like you have some circular include dependencies that you need to sort out.

For example:
Tile.h includes Game.h which includes TileMap.h which includes Tile.h.

This means that if you include Tile.h in one of your source files it will indirectly include TileMap.h, but TileMap.h will not include Tile.h because it has already been included (“#pragma once” prevents it from being included again). This leads to a situation where the content of TileMap.h is being compiled before the compiler has seen the content of Tile.h. I think this is why you get an error when group_of_tiles is declared, because the Tile class has not been declared yet.


Here is a simplified example just to demonstrate what happens:

// Tile.h
#pragma once
#include "Game.h"
class Tile {};
// Game.h
#pragma once
#include "TileMap.h"
class Game {};
// TileMap.h
#pragma once
#include "Tile.h"
#include <vector>
extern std::vector<Tile*> group_of_tiles;
class TileMap {};
// Test.cpp
#include "Tile.h"

Now let’s step through what happens when the preprocessor includes the content of the files in the Test.cpp translation unit. First the content of Tile.h is included:

#include "Game.h"
class Tile {};

Next the content of Game.h is included:

#include "TileMap.h"
class Game {};
class Tile {};

Then the content of TileMap.h is included:

#include "Tile.h"
#include <vector>
extern std::vector<Tile*> group_of_tiles;
class TileMap {};
class Game {};
class Tile {};

Tile.h is not included because it has already been included so what the Test.cpp translation unit will look like to the compiler (ignoring the inclusion of <vector>) is this:

#include <vector>
extern std::vector<Tile*> group_of_tiles;
class TileMap {};
class Game {};
class Tile {};

This will not compile because you’re trying to declare a vector of Tile pointers before the compiler knows what Tile is. Tile is not defined until later.


What you need to do is get rid of all such circular includes. Start by removing all includes from the headers that are not necessary.

Looking at your real code that you have uploaded on github I see that:

  • Entity.h does not need to include Game.h.
  • Game.h does not need to include Entity.h, TileMap.h, Tile.h and Layout.h.
  • Layout.h does not need to include Tile.h.
  • Tile.h does not need to include Game.h and Layout.h.

This probably means you will need to add some of these includes to the corresponding .cpp files instead.

After you have removed these unnecessary includes I think it should work. Later you might of course have to readd some of the includes as you add more code but you need to avoid creating a circle.


If removing unnecessary includes is not enough to avoid a circle you might want to consider using “forward declarations”.

Strictly speaking, TileMap.h doesn’t need to include Tile.h. Instead you could use a forward declaration.

class Tile; // "forward declaration" (this merely declares the Tile class without defining it)
extern std::vector<Tile*> group_of_tiles;

This works because the compiler doesn’t need to know what the Tile class look like in order to be able to deal with Tile pointers. The same is true for references and parameters of function declaration (not definitions).

class Tile;
void foo(Tile t); // This is OK

Personally I try to use forward declarations (for my own class types) instead of includes whenever possible and I rarely run into circular include problems.

That said, some might argue that we should not have circular dependencies in the first place and that we should design the code in such a way that we don’t need this. My understanding is that the new C++ “module” feature, that aims to be a modern replacement for headers and includes, does not support forward declarations between modules.


Another reason to reduce the number of includes is to improve compile times. If you make a change to one of your header files it means all .cpp files where the modified header file is included (directly or indirectly) needs to be recompiled. If it’s included in fewer files it means there is less code that needs to be recompiled which saves time.

2 Likes

So if I understand, instead of #include "Tile.h" you want me to just forward declare like: class Tile.
And you want me to follow this fashion for other files too. And, I removed most of the circular includes I didn’t need. Thank you!

Yes. I think it’s a good idea. It’s the way I would do it.

Note that you cannot always replace includes by forward declarations. In many situations the class definition is necessary so you need to include the header file.

This matters mostly for header files. In .cpp files you can include header files all you want without running into problems with circular includes (assuming there is no problem with the headers).

2 Likes

Oh ok, got it. Also as of now I’m checking collision of player against all tiles simultaneously, is there a way to check collision with tiles near the player? The way I think it can be done is creating a rect called proximity and checking collision of this rect that moves with the player, if proximity collides with a tile then check collision only against that tile. Or, is there a better way?

Forgive me if I’m missing something but isn’t that just introducing one extra step? Instead of looping over all tiles and check if they collide with the player you’re now thinking of looping over all tiles and checking if they collide with some other rect that covers the player and if they are you only then check them against the player? I guess this could make sense if collision detection against the player is more complicated (e.g. pixel-perfect collision detection) and you want to avoid having to do it for each tile but if it’s just a rect then I don’t see the point.

Yeah, use the player’s position to calculate the indices (columns and rows) of the tiles in the map that the player overlap.

The x-coordinate of the left side of the player will give you a tile column to start at (let’s call this col1).
The x-coordinate of the right side of the player will give you another tile column (col2).
Similarly, the y-coordinates of the top and bottom sides of the player will give you two rows (row1 and row2)

Once you have calculated col1, col2, row1 and row2 you can then simply loop over all the tiles that the player overlaps. Something like this:

for (int c = col1; c <= col2; ++c)
{
	for (int r = row1; r <= row2; ++r)
	{
		if (tileMap[c][r] == 'X')
		{
			// Collision...
		}
	}
}

Note that I have not made any assumptions about the size of the player here.

I tried to make “col” correspond to the x-axis and “row” to the y-axis the way you had it in your code above but you might want to verify that it is correct. I’m actually a bit confused by your code and wonder if you haven’t swapped the x and y-axis, at least if you want the tiles to appear in the same direction as the tile_map appears in the code.

2 Likes

Thank you, I will surely implement this!