unique_ptr列表中的访问冲突

Access Violation in unique_ptr list

本文关键字:访问冲突 列表 ptr unique      更新时间:2023-10-16

我有一个unique-ptrslist,在清除列表时,给出以下错误:

Unhandled exception at 0x013EA350 in Last.exe: 0xC0000005: Access violation reading location 0xFEEEFEEE.

这是在迭代元素时在 std::list 文件中触发的。问题有点独特:

  1. MenuManager具有unique_ptr<Menu>对象的列表。
  2. Menu具有unique_ptr<MenuItem>对象的列表。
  3. 第一个Menu及其所有MenuItems完美地破坏,但是这个错误是在清除MenuManager列表中的第二个Menu时触发的,具有完全独立的MenuItems。看起来好像第二个unique_ptr<Menu>在第一个毁灭之后变得不确定,尽管它在MenuManager毁灭之初就存在并且不是空的。

是什么原因造成的?(具体来说,不是在我的代码中导致此错误的位置。我想知道这通常是什么原因(

菜单管理器.h

class MenuManager
{
public:
    /*MenuManager(list<Menu*> menus) 
        : m_menus(menus) { SetMenu( menus.front() ); }*/
    MenuManager() : m_currentMenu(nullptr) {}

    // Get the menu that the manager is pointing to.
    Menu* GetCurrentMenu(void) { return m_currentMenu; }
    // Set the current menu based on its name.
    void SetMenu(string menuName) { SetMenu( GetMenuByName(menuName) ); }
    // Add a menu to the list of menus managed by this object.
    void AddMenu(Menu* menu);
    // Render the current menu.
    void RenderMenu(void) { m_currentMenu->Render(); }
private:
    list< unique_ptr<Menu> > m_menus; // The list of menus managed by this object
    Menu* m_currentMenu; // A pointer to the menu in current use
    Menu* GetMenuByName(string menuName);
    void SetMenu(Menu* menu); // Set the menu based on the menu argument
};

Menu是另一个基本上无关紧要的类的子类。但是,其列表定义为 list< unique_ptr<MenuItem> > . MenuItem的定义是无关紧要的。

您没有显示足够的代码来查明错误,但错误不言自明......

Last.exe: 0xC0000005 中0x013EA350未处理的异常: 访问违规读取位置0xFEEEFEEE。

在 Visual Studio 下的调试模式下,释放的内存设置为代码0xFEEE。因此,指针被释放了两次。

请注意,我看到管理器有一个 std::指针列表,它实际上并没有管理:你有一个带有裸指针的AddMenu()

我强烈建议您将std::unique_ptr替换为 std::shared_ptr ,无处不在,并且永远不要在任何地方使用裸指针(除非调用需要此类裸指针的较低级别的 API。共享指针的巨大优点是,您可以让许多类保存对它的引用,如果一个类死亡,其他类仍然具有有效的指针。如果您有父/子引用,请确保对子项中的父指针使用 std::weak_ptr