1
Window / Access violation in RenderWindow::GetEvent
« on: August 18, 2011, 04:42:23 pm »
All right, I understand why DestroyWindow and so forth should not always be called. However, I think you missed my point regarding SetWindowLongPtr.
In particular, on line 83 of WindowImplWin32.cpp, the WindowImplWin32 being created is assigned as custom data to the provided window handle:
or, in the case of non-external windows (which is what we have), on line 815:
But in the destructor this association between the window handle and the WindowImplWin32 object is not broken. The window may be about to be destroyed, but it has not been destroyed yet, and if the window is sent a message before it is destroyed, it will fetch that pointer to the now deallocated WindowImplWin32, and access it. And this does in fact happen.
By adding something like
to the destructor, this would be protected against. In fact, you have an if-guard on line 822 for that very purpose.
Quote from: "Laurent"
SetWindowLongPtr assigns custom data to a window. So there's no point assigning something to a window that is going to be destroyed.
In particular, on line 83 of WindowImplWin32.cpp, the WindowImplWin32 being created is assigned as custom data to the provided window handle:
Code: [Select]
WindowImplWin32::WindowImplWin32(WindowHandle handle) :
//...
{
if (myHandle)
{
//...
SetWindowLongPtr(myHandle, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(this)); // line 83
myCallback = SetWindowLongPtr(myHandle, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(&WindowImplWin32::GlobalOnEvent));
}
}
or, in the case of non-external windows (which is what we have), on line 815:
Code: [Select]
// Associate handle and Window instance when the creation message is received
if (message == WM_CREATE)
{
// Get WindowImplWin32 instance (it was passed as the last argument of CreateWindow)
LONG_PTR window = (LONG_PTR)reinterpret_cast<CREATESTRUCT*>(lParam)->lpCreateParams;
// Set as the "user data" parameter of the window
SetWindowLongPtr(handle, GWLP_USERDATA, window); // line 815
}
But in the destructor this association between the window handle and the WindowImplWin32 object is not broken. The window may be about to be destroyed, but it has not been destroyed yet, and if the window is sent a message before it is destroyed, it will fetch that pointer to the now deallocated WindowImplWin32, and access it. And this does in fact happen.
By adding something like
Code: [Select]
if (myHandle)
SetWindowLongPtr(myHandle, GWLP_USERDATA, NULL);
to the destructor, this would be protected against. In fact, you have an if-guard on line 822 for that very purpose.