复制QList导致分段错误

时间:2018-08-17 12:03:11

标签: c++ qt memory segmentation-fault qlist

最后,我遇到了一个非常疯狂的Segfault。我没有对源代码做任何事情,我唯一可能做的就是更新我的QT Creator和MinGW。现在,我的程序会导致分段错误,然后才能完美运行。

void Parameter::calculateKeyframes() {
    auto kfs = Bezier::calculateControlPoints(keyframes.values());
    for (auto kf : kfs) {
        setKeyframe(kf);
    }
    paramUpdate();
}

当它使用有效的“关键帧”映射运行此函数时,由于调试,我知道它在以下标记行的Bezier :: calculateControlPoints(QList)函数中崩溃。

QList<Keyframe> calculateControlPoints(QList<Keyframe> keyframes) {
    if (keyframes.size() < 2) {
        return keyframes;
    }

    int n = keyframes.size();
    for (int i = 0; i<n; i++) {
        Keyframe last_kf(0, ValueDouble(0.0));
        Keyframe kf;
        kf = keyframes.at(i);
        Keyframe next_kf(0, ValueDouble(0.0));

        if (-1 < i-1) last_kf = keyframes[i-1];
        else last_kf.frame = -1;

        if (keyframes.size() > i+1) next_kf = keyframes[i+1];
        else next_kf.frame = -1;

        if (kf.mode == Keyframe::STEP || kf.mode == Keyframe::LINEAR) continue;

        if (next_kf.frame > -1 && (kf.mode == Keyframe::EASEIN || (kf.mode == Keyframe::EASE && last_kf.frame < 0))) {
            double vecx_TtN = (double)next_kf.frame - (double)kf.frame; // vx = nx - x
            double vecy_TtN = next_kf.data.toDouble() - kf.data.toDouble(); // vy = ny - y

            kf.control2x = (double)kf.frame + vecx_TtN / 4.5; // x = x + vx / 4.5
            kf.control2y = (vecy_TtN / vecx_TtN) * (kf.control2x - kf.frame) + kf.data.toDouble(); // y = m * x + t
        } else if (last_kf.frame > -1 && (kf.mode == Keyframe::EASEOUT || (kf.mode == Keyframe::EASE && next_kf.frame < 0))) {
            double vecx_TtL = (double)last_kf.frame - (double)kf.frame; // vx = lx - x
            double vecy_TtL = last_kf.data.toDouble() - kf.data.toDouble(); // vy = ly - y

            kf.control1x = (double)kf.frame + vecx_TtL / 4.5; // x = x + vx / 4.5
            kf.control1y = (vecy_TtL / vecx_TtL) * (kf.control1x - kf.frame) + kf.data.toDouble(); // y = m * x + t
        } else if (kf.mode == Keyframe::EASE && last_kf.frame > -1 && next_kf.frame > -1) {
            double vecx_TtL = (double)last_kf.frame - (double)kf.frame; // vx = lx - x
            double vecx_TtN = (double)next_kf.frame - (double)kf.frame; // vx = nx - x

            double vecx_LtN = (double)next_kf.frame - (double)last_kf.frame; // vx = nx - lx
/* ---> */  double vecy_LtN = next_kf.data.toDouble() - last_kf.data.toDouble(); // vy = ny - ly

            kf.control1x = (double)kf.frame + vecx_TtL / 4.5; // x = x + vx / 4.5
            kf.control2x = (double)kf.frame + vecx_TtN / 4.5; // x = x + vx / 4.5
            kf.control1y = (vecy_LtN/vecx_LtN) * (kf.control1x - kf.frame) + kf.data.toDouble(); // y = m * x + t
            kf.control2y = (vecy_LtN/vecx_LtN) * (kf.control2x - kf.frame) + kf.data.toDouble(); // y = m * x + t
        }

        keyframes[i] = kf;
    }

    return keyframes;
}

这是在第二次循环运行中引起的,因为“ QList关键帧”在其成员中的索引为0(这意味着在第二次运行中,该成员也被复制到“ last_kf”),在关键帧中无效的指针地址“数据”指针。现在我的问题是,为什么数据现在是无效的指针……在Parameter :: calculateKeyframes()中却不是。

这是我的Keyframe.cpp(如果重要):

#include "keyframe.h"

#include "value.h"
#include "valuedouble.h"
#include <iostream>

Keyframe::Keyframe(long frame, Value v) : frame(frame), control1x(frame), control2x(frame), data(v), control1y(v), control2y(v) {
}

Keyframe::Keyframe() : Keyframe(0.0, ValueDouble(0.0)) {}

void Keyframe::toPipeKF(tutorial::Keyframe* k) {
    k->set_mode((tutorial::Keyframe_Mode)(int)mode);
    k->set_frame(frame);
    k->set_data((const char*)data.toByteArray());
    k->set_control1x(control1x);
    k->set_control1y(control1y.toByteArray());
    k->set_control2x(control2x);
    k->set_control2y(control2y.toByteArray());
}

Keyframe.h:

#ifndef KEYFRAME_H
#define KEYFRAME_H

#include "pipeendpoint.h"

#include "value.h"

class Keyframe {
public:
    Keyframe(long frame, Value v);
    Keyframe();

    enum Mode {
        STEP,
        LINEAR,
        EASEIN,
        EASE,
        EASEOUT,
        EASEFIX,
        EASECUSTOM
    };
    Mode mode = EASE;
    Value data;
    long frame;
    double control1x = 0;
    Value control1y;
    double control2x = 0;
    Value control2y;

    void toPipeKF(tutorial::Keyframe* kf);
};

#endif // KEYFRAME_H

0 个答案:

没有答案