代码之家  ›  专栏  ›  技术社区  ›  metablaster

使用静态std::vector类成员时的访问冲突

  •  0
  • metablaster  · 技术社区  · 6 年前

    下面是具有堆栈跟踪的类方法的代码快照:

    基窗口.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...
    
    };
    

    基本窗口.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;
    }
    

    这就是声明/定义有问题的静态向量的地方

    #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 { };
    

    中的0x00007FFA691212DE(vcruntime140d.dll)处引发异常 0x000001A35C589000。

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

    UI.dll!STD::ActhopyMeMeMeStun(未签名的短*1,未签名的短*最后,未签名的短**)1745线C++

    UI.dll!std::“未初始化”move>(无符号短*常量优先,无符号短*常量最后,无符号短*目标,

    UI.dll!std::vector>::重新分配(无符号短*

    UI.dll!std::vector>::emplace_back(const unsigned short& 第659行C++

    UI.dll!wsl::ui::BaseWindow::RegisterCls(const tagWNDCLASSEXW& Wndl类)第131行C++

    UI.dll!wsl::ui::主窗口::初始化(HINSTANCE\uuu*HINSTANCE,int dwStyle、无符号长dwExStyle、HICON HICON、humenu) 第68行C++

    TestUI.exe!测试主窗口(HINSTANCE\uu*HINSTANCE,HINSTANCE\u* HCPRATE,WCHARGET*LPCFDLINE,INTCMCDSH)第45行C++

    你觉得这段代码有什么问题吗?我的向量初始化是否正确?如果是,那么为什么push_back失败?

    0 回复  |  直到 6 年前
        1
  •  1
  •   HolyBlackCat    6 年前

    你可以用梅尔的单曲:

    而不是:

    static std::vector<ATOM> mAtoms;
    

    生成函数:

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

    静态销毁令 -可能是也可能不是问题-


    或者您可以尝试进行内联初始化-这可能会移动init。在初始阶段。命令。

     static inline std::vector<ATOM> mAtoms;
    

    并删除.cpp init。


    很可能 它是 导致堆损坏的向量

    您需要调试堆损坏。 在windows上,一个好的开始是 _CrtSetDbgFlag

    推荐文章