I got a Window
class that is a wrapper to some C struct.
The class has a static vector<Window*> windows_
that is a list containing created windows.
Window
constructor does two things:
handle_ = SDL_CreateWindow( ... );
that basically allocates the C struct and store the pointer in a member variable handle_
;this
in the list.Window
destructor does three things but only if handle_
is not a nullptr
:
SDL_DestroyWindow()
deallocates the C struct;this
from the list.handle_ = nullptr;
Then, in my main
I declare a Window
as a local variable.
When the window receives the CLOSE
event, I call that window's destructor.
Then, when the window goes out of scope, the window's destructor gets called again and I receive a segmentation error.
I know expicitly calling a destructor is delicate but I don't really know why.
So the question is twofold:
Why is it crashing?
What design can I use to avoid calling the destructor?
You should post some code so we can see exactly what is happening, but you're right that you shouldn't manually call the destructor because that will cause undefined behavior (see AliciaBytes' answer). Instead, add a method to the class to close the window, and use the class to provide a safe interface to the SDL window functions. Here is a sketch:
class Window {
private:
SDL_Window *window_;
public:
Window() : window_(nullptr) { }
Window(const Window &) = delete;
Window(Window &&w) : window_(w.window_) { w.window_ = nullptr; }
Window(const char* title, int x, int y, int w, int h, Uint32 flags)
: window(SDL_CreateWindow(title, x, y, w, h, flags))
{ }
~Window()
{
if (window_ != nullptr)
SDL_DestroyWindow(window_);
}
Window &operator=(const Window &) = delete;
Window &operator=(Window &&w)
{
if (window_) { SDL_DestroyWindow(window_); window_ = nullptr; }
window_ = w.window_;
w.window_ = nullptr;
}
operator bool() const
{
return window_ != nullptr;
}
void close()
{
if (window_ != nullptr) {
SDL_DestroyWindow(window_);
window_ = nullptr;
}
}
};