std::vector 使用 back()、pop_back()、push_back(),得到“双重释放或损坏”错误

Posted

技术标签:

【中文标题】std::vector 使用 back()、pop_back()、push_back(),得到“双重释放或损坏”错误【英文标题】:std::vector using back(), pop_back(), push_back(), get 'double free or corruption' error 【发布时间】:2018-05-23 23:49:55 【问题描述】:

我有以下代码:

struct branchInfo
    Quaternion r;
    Vector3 p;

    std::vector<Vector3> branchPoints;
;

std::vector<Vector3> LSystem::Turtle()

    std::vector<branchInfo> b;

    // The axiom should always start with a '[' at the start and a ']' at the end
    for(unsigned int i = 0; i < axiom.length(); i++) 
        char c = axiom[i];

        if (c == '[') 
            branchInfo temp;

            temp.r = rotationQuat;
            temp.p = position;
            temp.branchPoints.push_back(position);

            b.push_back(temp);
         else if (c == ']') 
            branchInfo temp = b.back();

            rotationQuat = temp.r;
            position = temp.p;
            branches.push_back(temp.branchPoints);

            b.pop_back();
         else 
            // Evaluate the character and move the turtle
            // F = move forward according to pitched, rolled, and yawed axis
            // f = move backward according to pitched, rolled, and yawed axis
            // p = pitch -45 degrees
            // P = pitch +45 degrees
            // r = roll -45 degrees
            // R = Roll +45 degrees
            // y = yaw -45 degrees
            // Y = yaw +45 degrees
            // [ = start new branch
            // ] = end new branch

            switch(c) 
            case 'f':
                b.back().branchPoints.push_back(Forward(-1.5f));
                break;
            case 'F':
                b.back().branchPoints.push_back(Forward(1.5f));
                break;
            case 'p':
                Pitch(-angle);
                break;
            case 'P':
                Pitch(angle);
                break;
            case 'r':
                Roll(-angle);
                break;
            case 'R':
                Roll(angle);
                break;
            case 'y':
                Yaw(-angle);
                break;
            case 'Y':
                Yaw(angle);
                break;
            
        
    

这段代码的重点是评估海龟将遵循的公理字符串。这是一个 L 系统,L 系统的部分要点是有分支,当有一个“[”字符时会发生这种情况,这意味着旋转和位置被保存并将在以后使用。例如,如果我的 L 系统类包含字符串 "[PPPPrrFp[[X]PX]pXRR]",我将收到以下错误: *** Error in /home/user/program/dist/Debug/GNU-Linux/world': double free or corruption (fasttop): 0x0000000003f43240 ***

我知道逐步完成这个程序并不容易,我不希望任何人这样做。我只是想知道是否很容易看出程序有什么问题。我知道该错误可能与使用某些 std::vector 方法/函数有关,但我不知道它为什么或如何导致它。

而且,它并不一致。有时程序会顺利运行,有时会因为我提到的错误而崩溃。

Yaw、Pitch 和 Roll 的功能应该无关紧要。

根据我的谷歌搜索,我只能在处理具有构造函数、析构函数的类以及删除数组等时找到此错误的示例。

感谢您的帮助!我希望很明显正在发生的事情并且不会花费太多时间。如果看起来确实需要太长时间,请不要打扰。再次感谢。

编辑:为了更容易理解函数中发生的事情,我将逐步解释函数: 从公理字符串的索引 0 开始,检查它是否开始一个新分支 ('['),如果是,则推送/保存 3D 向量 pos 和 rot -> 如果当前字符不是 '[' 或 '] ' 然后移动 pos 或 rotate -> 如果分支结束 (']') 从上次保存的 pos 和 rot 中恢复,并弹出堆栈顶部 -> 继续处理字符串中的每个字符。

【问题讨论】:

这可能与Vector3 类没有一组正确协同工作的构造函数、析构函数和赋值运算符有关。查找三规则(C++ 11 之前)、五规则(C++ 11 或更高版本)和零规则(C++ 11 或更高版本)。 Axiom[] 中有什么? 虽然std::vector 的实现可能存在错误,但大多数编译器的此类代码通常都经过了很好的验证。但是std::vector 假定它包含的对象可以正常播放。 假设您从 Vector3 获得的库是正常的,它应该符合 3/5/0 的规则,并且与 std::vector 一起使用不会导致任何问题。问题出在其他地方,在您没有向我们展示的代码中。 @JustHeavy 它与Vector3 无关 - 问题是您缺少返回语句。你应该阅读警告。当然,将函数返回类型更改为 void 解决了这个问题。 【参考方案1】:

万一将来有人遇到这个问题。即使我为函数指定了非 void 返回类型,我做错的是没有在函数中返回任何内容。将返回类型更改为 void 解决了我的问题。

【讨论】:

仅供参考:有编译器警告可以检测此类问题,它们可以为您节省大量时间

以上是关于std::vector 使用 back()、pop_back()、push_back(),得到“双重释放或损坏”错误的主要内容,如果未能解决你的问题,请参考以下文章

std::vector 向下调整大小

std::vector::emplace_back 比 std::vector::push_back 慢的示例?

想简化我的 std::vector push_back 使用

正确使用用户定义类型的 std::vector.push_back()

使用 `std::copy()` 和 `std::back_inserter()`

std::stack 是不是公开迭代器?