简体   繁体   English

使用 static std::vector class 成员时访问冲突

[英]Access violation when using static std::vector class member

Every 50th or so time I got access violation in my DLL implementing UI, mostly run time is just fine, I suspect this could be due to usage of static vector:每 50 次左右我在实现 UI 的 DLL 中遇到访问冲突,大部分运行时间都很好,我怀疑这可能是由于使用了 static 向量:

Here is code snapshot from class methods with stack trace:这是 class 方法的代码快照,带有堆栈跟踪:

BaseWindow.hpp基础窗口.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 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 This is where problematic static vector is declared/defined ClassAtoms.hpp这是声明/定义有问题的 static 向量的地方

#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类原子.cpp

SUPPRESS(26426);  // Global initializer calls a non-constexpr function
std::vector<ATOM> ClassAtoms::mAtoms { };

And here is relevant stack trace:这是相关的堆栈跟踪:

Exception thrown at 0x00007FFA691212DE (vcruntime140d.dll) in TestUI.exe: 0xC0000005: Access violation reading location 0x000001A35C589000.在 TestUI.exe 中的 0x00007FFA691212DE (vcruntime140d.dll) 处引发异常:0xC0000005:访问冲突读取位置 0x000001A35C589000。

vcruntime140d.dll!memcpy_repmovs() Line 114 Unknown vcruntime140d.dll!memcpy_repmovs() 第 114 行未知

UI.dll:std:,_Copy_memmove(unsigned short * _First, unsigned short * _Last, unsigned short * _Dest) Line 1745 C++ 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) Line 1738 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>) Line 707 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>) Line 659 C++ UI.dll:std::vector>::emplace_back(const unsigned short & <_Val_0>) 第 659 行 C++

UI.dll:wsl::ui::BaseWindow::RegisterCls(const tagWNDCLASSEXW & wnd_class) Line 131 C++ UI.dll:wsl::ui::BaseWindow::RegisterCls(const tagWNDCLASSEXW & wnd_class) 第 131 行 C++

UI.dll:wsl::ui::MainWindow:,Initialize(HINSTANCE__ * hInstance, int x, int y, int width, int height, HWND__ * hParent, unsigned long dwStyle, unsigned long dwExStyle, HICON__ * hIcon, HMENU__ * hMenu) Line 68 C++ UI.dll:wsl::ui::MainWindow:,Initialize(HINSTANCE__ * hInstance, int x, int y, int width, int height, HWND__ * hParent, unsigned long dwStyle, unsigned long dwExStyle, HICON__ * hIcon, HMENU__ * hMenu ) 线 68 C++

TestUI.exe,TestMainWindow(HINSTANCE__ * hInstance, HINSTANCE__ * hPrevInstance, wchar_t * lpCmdLine, int nCmdShow) Line 45 C++ TestUI.exe,TestMainWindow(HINSTANCE__ * hInstance, HINSTANCE__ * hPrevInstance, wchar_t * lpCmdLine, int nCmdShow) 第 45 行 C++

[External Code] [外部代码]

Do you see any problem with this code, is my vector initialized properly if so then why push_back fails?您是否看到此代码有任何问题,如果正确初始化了我的向量,那么为什么 push_back 会失败?

You could just use a meyer's singleton:您可以只使用迈耶的 singleton:

instead of:代替:

static std::vector<ATOM> mAtoms;

make a function:制作 function:

static auto& atoms() {
  static std::vector<ATOM> s;
  return s;
}

Now the vector is initialized on first use.现在向量在第一次使用时被初始化。 This also affects static destruction order - which may or may not be an issue - but you should be aware of it .这也会影响static 销毁顺序- 这可能是也可能不是问题 -但您应该注意这一点


Alternatively you could try with an inline initialization - this can likely move the init.或者,您可以尝试使用内联初始化 - 这可能会移动 init。 up in init.在初始化中。 order.命令。

 static inline std::vector<ATOM> mAtoms;

and remove the.cpp init.并删除.cpp init。


That being said, it is very likely that it is not that vector causing the heap corruption .虽如此,很可能不是那个向量导致了堆损坏

You need to debug heap corruptions.您需要调试堆损坏。 On windows a good start is _CrtSetDbgFlag在 windows 上一个好的开始是_CrtSetDbgFlag

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM