C++, Win32 and Memory Issues

It’s been ages since I’ve done something in C++, but with the new developments – especially c++11 (and to do something different than what I do at work), I’ve decided to do my own Tetris clone.

I’ve had very little free time, so the project’s mostly moved forward quite slowly. One day, I decided to port it to Ubuntu via SDL. The approach is rather ineffective – with two separate code paths – because I decided to keep the D2D code path intact.

In order to do this, I’ve utilized the pimpl idiom. This basically means that the class is separate in public interface and implementation details, which become opaque.

Before the pimpl refactoring, I used to have this in my Win32 code:

m_window = ::CreateWindowExW(exStyle, APP_CLASS, APP_TITLE,
    windowStyle, x, y, width, height, HWND_DESKTOP, nullptr, m_instance,
    reinterpret_cast<void*>(this));

… and in WndProc, the usual shenanigans:

if (message == WM_CREATE) {
  CREATESTRUCT* createData = reinterpret_cast<CREATESTRUCT*>(lparam);
  Game* game = reinterpret_cast<Game*>(createData->lpCreateParams);

  ::SetWindowLongPtr(window, GWLP_USERDATA,
#ifdef _WIN64
    reinterpret_cast<LONG_PTR>(game)
#else
    reinterpret_cast<LONG>(game)
#endif
    );
  return 0;
} else {
  Game* game = reinterpret_cast<Game*>(::GetWindowLongPtr(window, GWLP_USERDATA));

Now, the problem is that with the move to pimpl, this changes its meaning… now the pointer we pass to CreateWindowEx is Game::Impl, instead of Game, while I still treated it as Game in WndProc. Of course, being pampered by managed languages such as C# and Java, it took me some time to actually find the problem 🙂

Conclusion: treat your memory with respect!