I don't want to show you a book so i am going to simplify. I have a class called "Tile" that looks similar to this:
class Tile{
public:
struct Type{ unsigned int uvIndex; ... };
Tile(Tile::Type* tt){ tt_ = tt; ... }
Type tt_ = nullptr;
Tile* getNorthEast(){
printf("this %p\n", this); //for debugging purposes
/* calculation; "this" pointer is need for that */
return northEastTilePtr;
}
};
I want to allocate many of them in one big array that will never move again (no need for a ) so i do that allocation manually
//Manual allocation to prevent constructor from being called
Tile* tiles = (Tile*)malloc(numTiles*sizeof(Tile));
if(tiles == nullptr) throw std::bad_alloc();
Since the Tile type is not known at first i cannot call new to do that. Now i have memory allocated, but no constructors called. The world generator runs and calls for each tile
tiles[tileIndex] = Tile(tileTypePtr);
Now it should have created all objects with all types.
If I render the scene and without calling getNorthEast();
I can see, that the types have been set correctly due to the uvIndex
(that just specifies which section of the texture to render). So tt_ is set correctly and the constructor must have run correctly too.
However! If i now call getNorthEast();
the printf statement tells me that the this
pointer is 00000000. This messes up the calculation and results in a crash.
It probably is due to undefined behaviour, but I do not see what I am doing wrong... I need your help for that.
EDIT 1: So I have now had a look at placement new. I have changed the allocation and assignment to:
//allocation
tiles = (Tile*)new char[numTiles*sizeof(Tile)];
//assignment
new (&tiles[tileIndex]) Tile(tileTypePtr);
However this
is still a nullptr. This time the assignment should be a complete overwrite without undefined behaviour. The allocation does essentially the same thing as std::vector.reserve()
;
Additional Info: the getNorthEast() is called much later in the main loop. Right now is just initialisation. It should therefore have no impact on wether the object is constructed or not.
Edit 2: I have just re-tried using a vector. same result.
std::vector<Tile> tiles;
//allocation
tiles_.reserve(numTiles);
//construction for each index
tiles.emplace_back(Tile(tileTypePtr));
Since neither vector nor doing it manually worked even with your input, i am starting to suspect the cause is some that I have not mentioned. I will keep looking until I find something else, that could cause trouble.