【发布时间】:2016-12-19 09:20:13
【问题描述】:
我在很多课程中都跟踪过这个问题,令我惊讶的是,这个错误的根源是一个简单的std::string = std::string 操作。
我不会发布整个代码,只是按顺序执行的函数。我仍然认为 SO 标准的代码太多,但我没有其他选择。
一些上下文说明:
- OrderedPair 是一个公共结构
{ int y, int x },位于单独的lib.inc文件中。 - 前导下划线标记函数头中声明的变量
- 尾随下划线标记类成员变量
ncefm.cc -- 基本上是主文件
std::vector<std::string> juststring = {"teststring", "another string", "foobar"};
List* list0 = new List(w0_, juststring); // Source of the error
list.cc -- 构造函数List()在这里被调用
忽略可选变量,反正它们不会被调用
List::List(Frame* const _parent, std::vector<std::string> &_list,
const OrderedPair &_pos = {0, 0}, const unsigned int &_spacing = 1,
const unsigned int &_maxsize = 0) {
pos_ = _pos;
size_ = _list.size();
spacing_ = _spacing;
maxsize_ = _maxsize;
parent_ = _parent;
Fill(_list); //Source of the error
Redraw();
parent_->AddWidget(this);
}
list.cc -- 成员函数Fill()
list_ 是 std::vector 类型的成员变量
void List::Fill(std::vector<std::string> &_list) {
for (unsigned int loop = size_; loop < (size_ + _list.size()); loop++) {
list_.push_back(new Label(parent_, _list[loop], {pos_.y + (loop * spacing_),
pos_.x}, maxsize_)); // source of the error (the constructor Label() )
}
}
label.cc -- 这里调用了构造函数Label()
Label::Label(Frame* const _parent, std::string &_text,
const OrderedPair &_pos = {0,0}, const unsigned int &_maxsize = 0) {
pos_ = _pos;
maxsize_ = _maxsize;
parent_ = _parent;
SetText(_text); // Source of the error
parent_->AddWidget(this);
}
list.cc -- 成员函数 SetText()
终于到了,错误的来源是……
void Label::SetText(std::string& _text) {
if (maxsize_ != 0 && _text.length() > maxsize_) _text.resize(maxsize_);
text_ = _text; // THIS?!
size_ = text_.length();
Redraw();
}
如果我只是注释掉这一行,错误就会消失, 当然,这会破坏功能。 text_.assign(_text);也不行。
label.h -- 显示一些变量text_的头文件和定义
class Label {
private:
OrderedPair pos_;
unsigned int size_;
unsigned int maxsize_;
std::string text_;
Frame* parent_;
public:
Label(Frame* const _parent, std::string &_text, const OrderedPair &_pos,
const unsigned int &_maxsize);
~Label();
inline const Frame* GetParent();
inline unsigned int GetSize();
inline std::string Text();
void SetText(std::string&);
void Move(const OrderedPair &_pos);
void RMove(const OrderedPair &_pos);
void Redraw();
void Clear();
};
如果这太乱了,或者您认为您需要有关我的课程的更多信息,请让我在此处添加它们,或者查看我在开发分支 here 上的 GitHub 存储库(公共)。
【问题讨论】:
-
你能给我们最小的、完整的、可编译的代码,我们可以用它来复制问题吗?
-
@DavidSchwartz 在我所有的 SO 问题中,我都尝试这样做,但是当我不知道如何在这种情况之外复制它时,我应该怎么做?在这种情况下,问题绝对出在错误消息指向我的其他地方 - 当它超出向量范围时没有出错......
-
@areuz
_list.at(loop)而不是_list[loop]会立即发现问题。此外,使用前导下划线命名变量也不是一个好主意,例如_list。 -
@PaulMcKenzie 嗯,很高兴知道,我会尝试,也许从现在开始使用它。为什么在你看来不好?我使用它,因为它与成员变量相反,成员变量后面带有下划线。
-
使用
at()作为健全性检查,以确保您不会越界。一旦你确定这一点,然后改回[ ]。至于前导下划线,带有前导下划线的名称是为编译器的实现保留的。我知道有些规则使用前导下划线是“安全的”,但它们对我来说太难记住了,所以我从不使用前导下划线。搜索 SO 将引导您找到解释这一点的线程。
标签: c++ debugging segmentation-fault c++14 ncurses