Why is `this` equal to 0x0, causing my program to crash?
c++, segmentation-fault, smart-pointers, this
Solution
The line
*_owner = owner;
means "make a copy of the `owner` object, and store it at the place that `_owner` points to." The problem is that `_owner` doesn't point to anything yet; it's still null.
If you really want to make a copy of the `Player` object in each tile that the player controls, you'd need to do
_owner.reset(new Player(owner));
But making copies of the `Player` object is a strange thing to do. Consider using `shared_ptr` instead — you can have both `owner` and `_owner` be `shared_ptr`s, and just assign one to the other in the usual way.
Problem
I'm designing a simple Connect 4 game. So far, I have 4 underlying classes: `Colour` - responsible for representing colours (RGBA). Includes conversion operators. `Player` - represents a player of the game. Each `Player` has a `Colour` and a name. `Board` - represents the playing board. It contains dimensions, as well as a 2D vector of `Tile`s with those dimensions. `Tile` - a nested class within `Board`. Represents one space on the board. Each `Tile` has a `Colour` and an `std::unique_ptr` to the owner of that tile. The owner starts as `nullptr` and can be changed once to a `Player`. The colour starts as a transparent black. I've tested my `Colour` class and it appears to be working fine. My `Player` class is in tip-top shape as well. However, I'm having some problems with the `Board/Tile` classes. My test consisted of creating two players, and a board. These executed normally. Next, I loop through the dimensions of the board, once for each tile. I then call ``` board.tile (j, i).claimBy (p2); ``` The loop goes through rows with `i` and columns with `j`, the way you'd expect to print it. `tile (j, i)` retrieves the tile I'm working with. It works as expected. Chain of Events Leading to the Crash: `claimBy (p2)` sets the tile to become claimed by player 2. It is implemented as follows: ``` bool Board::Tile::claimBy (const Player &owner) { if (!_owner) { *_owner = owner; _colour = owner.colour(); return true; } return false; } ``` `_owner` is my `std::unique_ptr<Player>`. It first checks whether the owner of the tile has been set before (i.e. is not `nullptr`). If not, it sets the `Player` inside to the one passed in. It then updates the tile's colour and returns `true`. If the tile has been previously claimed, it returns `false`. Following the debugger, the crash occurs in the line `*_owner = owner;`. Stepping in takes me to the line `struct Player` (my declaration of the `Player` class), which I take to be the implicit copy constructor (remember the class only has a `Colour _colour` and a `std::string _name`). Stepping in again leads me to `Colour::operator=` (which makes sense for a copy constructor to call). Here's the definition: ``` Colour &Colour::operator= (const Colour &rhs) { if (*this != rhs) { _red = rhs.red(); _green = rhs.green(); _blue = rhs.blue(); _alpha = rhs.alpha(); } return *this; } ``` The path turns into `*this != rhs`. This is just a reverse call to `operator==`, which is: ``` return red() == rhs.red() && green() == rhs.green() && blue() == rhs.blue() && alpha() == rhs.alpha(); ``` The first comparison here `red() == rhs.red()` has `red()` which is just `return _red;`. This is the point at which the program crashes. The debugger states that `this` (`this->_red`) is 0x0. I'm clueless about why this is happening. My best guess is that I'm using the smart pointer wrongly. I've never actually used one before, but it should be pretty similar to normal pointers, and I didn't think `release` would accomplish anything if the pointer is `nullptr`. What could be the cause of `this` being 0x0? Edit: I'm sure everything is initialized, as I do so in each constructor, in member initializers (e.g. `Board::Tile::Tile() : _colour (Colours::NONE), _owner (nullptr){}`), where NONE is a transparent black. I'm also not too proficient with a debugger, as I haven't used it that much over printing debugging values.