簡體   English   中英

使用 static std::vector class 成員時訪問沖突

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

每 50 次左右我在實現 UI 的 DLL 中遇到訪問沖突,大部分運行時間都很好,我懷疑這可能是由於使用了 static 向量:

這是 class 方法的代碼快照,帶有堆棧跟蹤:

基礎窗口.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這是聲明/定義有問題的 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);
}

類原子.cpp

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

這是相關的堆棧跟蹤:

在 TestUI.exe 中的 0x00007FFA691212DE (vcruntime140d.dll) 處引發異常: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, 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) 第 45 行 C++

[外部代碼]

您是否看到此代碼有任何問題,如果正確初始化了我的向量,那么為什么 push_back 會失敗?

您可以只使用邁耶的 singleton:

代替:

static std::vector<ATOM> mAtoms;

制作 function:

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

現在向量在第一次使用時被初始化。 這也會影響static 銷毀順序- 這可能是也可能不是問題 -但您應該注意這一點


或者,您可以嘗試使用內聯初始化 - 這可能會移動 init。 在初始化中。 命令。

 static inline std::vector<ATOM> mAtoms;

並刪除.cpp init。


雖如此,很可能不是那個向量導致了堆損壞

您需要調試堆損壞。 在 windows 上一個好的開始是_CrtSetDbgFlag

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM