delete_scalar.cpp 中的“_CRTDECL 运算符删除”中的删除触发异常
delete triggers exception in "_CRTDECL operator delete" in delete_scalar.cpp
我正在用 C++ 编写 WinAPI 应用程序。
情况
我在 wWinMain
中初始化 Interface
class 并将指向它的指针存储到 GWLP_USERDATA
中,如下所示:
WinMain(...)
{
...
// INITIALIZE CUSTOM INTERFACE
Interface* p_inface{new Interface(hWnd)}; // Create class object
SetWindowLongPtrW(hWnd, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(p_inface)); // to retrieve it in callback
...
}
我这样初始化它是因为 Interface
class 初始化需要 HWND
的子 classed 控件已经存在,我更喜欢我的 classes 在构造函数中自动完全初始化。
在我的 WndProc
回调中,我想像这样删除它:
WndProc(...)
{
...
case WM_NCDESTROY:
{
Interface* p_inface{reinterpret_cast<Interface*>(GetWindowLongPtrW(hWnd, GWLP_USERDATA))};
delete p_inface;
}
break;
...
}
Interface
class header:
class Interface
{
public:
Interface(HWND const hWndParam);
~Interface();
private:
std::shared_ptr<Time> const p_time; // object holding timeframe information
std::unique_ptr<Calendar> const p_calendar; // object handling calendar interface
std::unique_ptr<MainMinimize> const p_minimize; // minimize button
std::unique_ptr<MainClose> const p_close; // close button
Interface(const Interface&) = delete;
Interface& operator=(const Interface&) = delete;
};
和class项目文件:
Interface::Interface
(
HWND const hWndParam // handle to main window
)
: p_time(std::make_shared<Time>())
, p_calendar{std::make_unique<Calendar>(p_time, hWndParam)}
, p_minimize{std::make_unique<MainMinimize>(hWndParam)}
, p_close{std::make_unique<MainClose>(hWndParam)}
{
}
Interface::~Interface()
{
}
问题
当应用程序尝试 delete
WndProc
的 WM_NCDESTROY
中的 p_inface
指针时,我得到指向此处(在 delete_scalar.cpp 中)的异常:
_CRT_SECURITYCRITICAL_ATTRIBUTE
void __CRTDECL operator delete(void* const block) noexcept
{
#ifdef _DEBUG
_free_dbg(block, _UNKNOWN_BLOCK); // << EXCEPTION: APPLICATION TRIGGERED BREAKPOINT
#else
free(block);
#endif
}
我不明白为什么。我尝试从内部 objects 中删除 const
(没有成功)并在析构函数中重置内部 Interface
class objects (这也没有成功)解决问题)。
调试的时候发现WndProc中的指针是正确的,里面的objects除了Time
shared_ptr
都已经被擦掉了。不过它们在 WM_DESTROY 消息中完好无损。
在寻找解决方案时,我发现它主要触发人们在堆栈上删除 objects 或将 new
与 delete[]
混合。 One person提到"Most likely, either the point is not pointing to a valid heap allocated object, the heap has already been deleted or some other code has corrupted the heap."
问题
你能帮我理解我犯了什么错误以及如何修复它以便不再触发异常吗?
问题不在于实际的 Interface
对象(感谢 molbdnilo!),而是基础 classes 之一中处理信息的顺序。
我的所有控件 class 子 class WinAPI 控件都存储在 unique_ptr
中 Interface
对象更深的对象中,依此类推 Interface
delete 语句级联析构函数导致所有 unique_ptr
s 自动销毁它们的对象。
问题是,当我通过 dwRefData 将 class 的指针(subclassing 控件)潜入它的回调函数时,我也在 deleting
它 WM_DESTROY 消息 - 但由于 unique_ptr
清理发生的时间早于 DESTROY
消息可能到达队列,该对象早已消失。
所以解决方案:不要尝试删除已经由智能指针处理的对象!
我正在用 C++ 编写 WinAPI 应用程序。
情况
我在 wWinMain
中初始化 Interface
class 并将指向它的指针存储到 GWLP_USERDATA
中,如下所示:
WinMain(...)
{
...
// INITIALIZE CUSTOM INTERFACE
Interface* p_inface{new Interface(hWnd)}; // Create class object
SetWindowLongPtrW(hWnd, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(p_inface)); // to retrieve it in callback
...
}
我这样初始化它是因为 Interface
class 初始化需要 HWND
的子 classed 控件已经存在,我更喜欢我的 classes 在构造函数中自动完全初始化。
在我的 WndProc
回调中,我想像这样删除它:
WndProc(...)
{
...
case WM_NCDESTROY:
{
Interface* p_inface{reinterpret_cast<Interface*>(GetWindowLongPtrW(hWnd, GWLP_USERDATA))};
delete p_inface;
}
break;
...
}
Interface
class header:
class Interface
{
public:
Interface(HWND const hWndParam);
~Interface();
private:
std::shared_ptr<Time> const p_time; // object holding timeframe information
std::unique_ptr<Calendar> const p_calendar; // object handling calendar interface
std::unique_ptr<MainMinimize> const p_minimize; // minimize button
std::unique_ptr<MainClose> const p_close; // close button
Interface(const Interface&) = delete;
Interface& operator=(const Interface&) = delete;
};
和class项目文件:
Interface::Interface
(
HWND const hWndParam // handle to main window
)
: p_time(std::make_shared<Time>())
, p_calendar{std::make_unique<Calendar>(p_time, hWndParam)}
, p_minimize{std::make_unique<MainMinimize>(hWndParam)}
, p_close{std::make_unique<MainClose>(hWndParam)}
{
}
Interface::~Interface()
{
}
问题
当应用程序尝试 delete
WndProc
的 WM_NCDESTROY
中的 p_inface
指针时,我得到指向此处(在 delete_scalar.cpp 中)的异常:
_CRT_SECURITYCRITICAL_ATTRIBUTE
void __CRTDECL operator delete(void* const block) noexcept
{
#ifdef _DEBUG
_free_dbg(block, _UNKNOWN_BLOCK); // << EXCEPTION: APPLICATION TRIGGERED BREAKPOINT
#else
free(block);
#endif
}
我不明白为什么。我尝试从内部 objects 中删除 const
(没有成功)并在析构函数中重置内部 Interface
class objects (这也没有成功)解决问题)。
调试的时候发现WndProc中的指针是正确的,里面的objects除了Time
shared_ptr
都已经被擦掉了。不过它们在 WM_DESTROY 消息中完好无损。
在寻找解决方案时,我发现它主要触发人们在堆栈上删除 objects 或将 new
与 delete[]
混合。 One person提到"Most likely, either the point is not pointing to a valid heap allocated object, the heap has already been deleted or some other code has corrupted the heap."
问题
你能帮我理解我犯了什么错误以及如何修复它以便不再触发异常吗?
问题不在于实际的 Interface
对象(感谢 molbdnilo!),而是基础 classes 之一中处理信息的顺序。
我的所有控件 class 子 class WinAPI 控件都存储在 unique_ptr
中 Interface
对象更深的对象中,依此类推 Interface
delete 语句级联析构函数导致所有 unique_ptr
s 自动销毁它们的对象。
问题是,当我通过 dwRefData 将 class 的指针(subclassing 控件)潜入它的回调函数时,我也在 deleting
它 WM_DESTROY 消息 - 但由于 unique_ptr
清理发生的时间早于 DESTROY
消息可能到达队列,该对象早已消失。
所以解决方案:不要尝试删除已经由智能指针处理的对象!