最后,我遇到了一个非常疯狂的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