【问题标题】:Valgrind Memory Leak in a multi-class level constructor for a dungeoncrawler in c++c++ 中地牢爬行者的多类级别构造函数中的 Valgrind 内存泄漏
【发布时间】:2020-06-05 13:28:45
【问题描述】:

我在当前使用 C++ 开发小型地牢爬行者的项目中遇到了小内存泄漏。 Valgrind 告诉我我正在泄漏0 bytes in 1 blocks are definetly lost in loss record 1 of 38, Location level.cpp:6:0 该行是我的构造函数定义。 我似乎无法找到问题所在,因为在我阅读了有关 Valgrind 的内容之后,对这个问题的唯一可能解释是,如果我创建了一个长度为 0 的数组,该数组将会丢失,但在我的代码中并非如此。

对于 valgrind 消息是如何发生的,还有其他解释吗?

我不想把代码上传到这里,因为项目相当大,我不确定代码是否有用。

编辑 1:

Level::Level(const std::string& levelFileName)
{

    auto nodes = loadNodesFromLevelFile(levelFileName);
    std::vector<Node> switches;
    std::vector<Node> portals;

    for(const auto& node : nodes)
    {
        const auto nodeName = node.name;
        if(nodeName == "Map Information")
        {
            setHeight(node.get<int>("rows"));
            setWidth(node.get<int>("cols"));
            m_gameboard = new Tile**[m_height];

            for(auto row = 0; row < m_height; ++row)
            {
                m_gameboard[row] = new Tile*[m_width];
            }
        }
        if(nodeName == "Wall")
        {
            auto col = node.get<int>("col");
            auto row = node.get<int>("row");
            m_gameboard[row][col] = new Wall(row, col);
        }
        if(nodeName == "Floor")
        {
            auto col = node.get<int>("col");
            auto row = node.get<int>("row");
            m_gameboard[row][col] = new Floor(row, col);
        }
        if(nodeName == "Door")
        {
            auto col = node.get<int>("col");
            auto row = node.get<int>("row");
            m_gameboard[row][col] = new Door(row, col);
        }
        if(nodeName == "Portal")
        {
            auto col = node.get<int>("col");
            auto row = node.get<int>("row");
            m_gameboard[row][col] = new Portal(row, col, nullptr);
            portals.push_back(node);
        }
        if(nodeName == "Switch")
        {
            switches.push_back(node);
        }
        if(nodeName == "Character")
        {
            auto col = node.get<int>("col");
            auto row = node.get<int>("row");
            auto icon = node.get<char>("icon");
            placeCharacter(new Character(icon), row, col);
        }
    }
    for(const auto& portalNode : portals)
    {
        const auto row = portalNode.get<int>("row");
        const auto col = portalNode.get<int>("col");
        const auto destRow = portalNode.get<int>("destrow");
        const auto destCol = portalNode.get<int>("destcol");

        auto* portal = static_cast<Portal*>(m_gameboard[row][col]);
        auto* destination = static_cast<Portal*>(m_gameboard[destRow][destCol]);
        portal->setDestination(destination);
    }



    for(const auto& s : switches)
    {
        const auto row = s.get<int>("row");
        const auto col = s.get<int>("col");
        const auto destRows = s.get<std::vector<int>>("destrows");
        const auto destCols = s.get<std::vector<int>>("destcols");

        auto* sw = new Switch(row, col);
        m_gameboard[row][col] = sw;
        for(ulong i = 0; i < destRows.size(); ++i)
        {
            auto* target = m_gameboard[destRows[i]][destCols[i]];
            sw->attach(dynamic_cast<Door*>(target));
        }
    }
}

这是我的关卡的构造函数(从第 6 行开始)。

【问题讨论】:

  • 您至少可以在“Location level.cpp:6:0”处显示代码,还是希望我们完全猜测?
  • 请参阅minimal reproducible example。整个代码库太多了,无法发布,但如果您可以减少重现问题所需的代码量,将会很有帮助。如果你幸运的话,试试main 构造你的对象然后退出的函数。如果 Valgrind 为此报告错误,请将类定义减少到保持泄漏所需的最低限度。 (您可能还会查找您的班级的 0 长度数组。不确定这是否会触发此消息,但值得研究。)
  • 使用容器类/智能指针,它们的存在是有原因的。除非您正在创建容器类或智能指针,否则切勿使用裸 new/delete。但即便如此,您也可以在现有容器的基础上进行构建。
  • 如何初始化m_widthm_height
  • 简单的setter函数``` void Level::setHeight(int height) { m_height = height; } void Level::setWidth(int width) { m_width = width; } ```

标签: c++ memory-leaks valgrind


【解决方案1】:

好的,现在我知道为什么我的程序会丢失字节。

在我的 level.h 中,我使用未初始化的 m_height 值初始化了 tile*** m_gameboard。

Tile*** m_gameboard = new Tile**[m_height];

在我的构造函数中被覆盖。因此丢失了 0 个字节。

感谢您的每一个建议。

【讨论】:

    猜你喜欢
    • 2013-01-12
    • 1970-01-01
    • 2021-11-28
    • 1970-01-01
    • 1970-01-01
    • 2020-03-31
    • 2016-03-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多