每隔50次左右,我的DLL实现UI中就会出现访问冲突,大多数情况下运行时间都很好,我怀疑这可能是由于使用了静态向量:
这里是带有堆栈跟踪的类方法的代码快照:
BaseWindow.hpp
#define UI_API __declspec(dllexport)
class UI_API BaseWindow
: public Object // base class for ref counting
{
// the rest of the code...
protected:
/** Register window class */
[[nodiscard]] virtual bool RegisterCls(const WNDCLASSEX& wnd_class) const;
/** fill in window class info struct */
[[nodiscard]] virtual bool GetClsInfo(const PCTSTR& class_name, WNDCLASSEX& wnd_class) const;
// the rest of the code...
};
BaseWindow.cpp
bool BaseWindow::GetClsInfo(const PCTSTR& class_name, WNDCLASSEX& wnd_class) const
{
if (mhInstance) // handle to HINSTANCE
{
if (GetClassInfoEx(mhInstance, class_name, &wnd_class))
return true;
else return false; // class does not exist, not an error
}
else // error handling
{
ShowError(Exception(GenericErrorCode::InvalidHandle, TEXT("Hinstance should not be nullptr")), ERR_BOILER);
return false;
}
}
bool BaseWindow::RegisterCls(const WNDCLASSEX& wnd_class) const
{
WNDCLASSEX wcex{};
// If the function does not find a matching class and successfully copy the data,
// the return value is zero.
if (!GetClsInfo(wnd_class.lpszClassName, wcex)) // calls above function!
{
// If the function fails, the return value is zero.
const ATOM atom = RegisterClassEx(&wnd_class);
if (!atom) // error handling
{
ShowError(ERR_BOILER);
return false;
}
else
{
ClassAtoms::AddClassAtom(atom); // call below function!
}
}
return true;
}
ClassAtoms.hpp这是声明/定义有问题的静态向量的地方
#define SUPPRESS(...) __pragma(warning(suppress : __VA_ARGS__))
class UI_API ClassAtoms
{
// the rest of the code...
public:
/** Add registered window class to ATOM container */
inline static void AddClassAtom(const ATOM& atom);
// the rest of the class
private:
/** Container for registered window classes */
SUPPRESS(4251); // needs to have dll-interface (inlining will result in internal compiler error)
static std::vector<ATOM> mAtoms;
// the rest of the code...
};
void ClassAtoms::AddClassAtom(const ATOM& atom)
{
mAtoms.push_back(atom);
}
ClassAtoms.cpp
SUPPRESS(26426); // Global initializer calls a non-constexpr function
std::vector<ATOM> ClassAtoms::mAtoms { };
这是相关的堆栈跟踪:
在以下位置抛出异常:0x00007FFA691212DE(vcruntime140d.dll)TestUI.exe:0xC0000005:访问冲突读取位置0x000001A35C589000。
vcruntime140d.dll!memcpy_repmovs()第114行未知
UI.dll!std :: _ Copy_memmove(unsigned short * _First,unsigned short * _Last,unsigned short * _Dest)行1745 C ++
UI.dll!std :: _ Uninitialized_move>(unsigned short * const _First,unsigned short * const _Last,unsigned short * _Dest,std :: allocator&_Al)1738行C ++
UI.dll!std :: vector> :: __ Emplace_reallocate(unsigned short *const _Whereptr,const unsigned short&<_val_0>)第707行C ++
UI.dll!std :: vector> :: emplace_back(const unsigned short&<_val_0>)659行C ++
UI.dll!wsl :: ui :: BaseWindow :: RegisterCls(const tagWNDCLASSEXW&wnd_class)第131行C ++
UI.dll!wsl :: ui :: MainWindow :: Initialize(HINSTANCE__ * hInstance,intx,int y,int width,int height,HWND__ * hParent,无符号长dwStyle,无符号长dwExStyle,HICON__ * hIcon,HMENU__ * hMenu)68行C ++
TestUI.exe!TestMainWindow(HINSTANCE__ * hInstance,HINSTANCE__ *hPrevInstance,wchar_t * lpCmdLine,int nCmdShow)第45行C ++
[外部代码]
您是否看到此代码有任何问题,如果正确,我的向量是否正确初始化,然后为什么push_back失败?
您可以只使用迈耶的单身人士:
而不是:
static std::vector<ATOM> mAtoms;
执行功能:
static auto& atoms() {
static std::vector<ATOM> s;
return s;
}
现在,向量在首次使用时被初始化。这也会影响静态销毁顺序-可能会或可能不会导致问题-但您应该意识到这一点。
或者,您可以尝试进行内联初始化-这可能会移动初始化。初始化。订单。
static inline std::vector<ATOM> mAtoms;
并删除.cpp init。
话虽这么说, 很可能导致堆损坏的向量是[[不是。
您需要调试堆损坏。在Windows上,一个不错的开始是_CrtSetDbgFlag