C++ 导致分段错误的简单字符串赋值?
我已经在我的很多类中跟踪了这个问题,它让我惊讶,这个错误的来源是一个简单的C++ 导致分段错误的简单字符串赋值?,c++,debugging,segmentation-fault,c++14,ncurses,C++,Debugging,Segmentation Fault,C++14,Ncurses,我已经在我的很多类中跟踪了这个问题,它让我惊讶,这个错误的来源是一个简单的std::string=std::string操作 我不会发布全部代码,只发布按顺序执行的函数。我仍然认为SO标准的代码太多,但我看不到其他选择 一些上下文注释: OrderedPair是一个单独的lib.inc文件中的公共结构{int y,int x} 前导下划线标记函数头中声明的变量 尾随下划线标记类成员变量 ncefm.cc——基本上是主文件 list.cc--成员函数Fill() list_uu是std::ve
std::string=std::string
操作
我不会发布全部代码,只发布按顺序执行的函数。我仍然认为SO标准的代码太多,但我看不到其他选择
一些上下文注释:
- OrderedPair是一个单独的
文件中的公共结构lib.inc
{int y,int x}
- 前导下划线标记函数头中声明的变量
- 尾随下划线标记类成员变量
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() )
}
}
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);也不行
label.h——显示某些变量的头文件和定义
如果这太混乱了,或者您认为需要关于我的类的更多信息,请让我将它们添加到这里,或者查看开发分支上的GitHub repo(public)。看起来您正在访问vector范围之外的元素(
\u list[loop]
):
for(unsigned int loop=size;loop<(size++\u list.size());loop++){
list_uu.push_uback(新标签(父标签,u列表[loop],{pos_u.y+(循环*间距),pos_u.x},maxsize_u));
看起来您正在访问向量范围之外的元素(\u list[loop]
):
for(unsigned int loop=size;loop<(size++\u list.size());loop++){
list_uu.push_uback(新标签(父标签,u列表[loop],{pos_u.y+(循环*间距),pos_u.x},maxsize_u));
C++实现的供应商往往会花费很多精力来消除标准库实现中的明显缺陷。因此,问题的实际原因是简单的<代码> STD::String 赋值非常小(大约为零)。
几乎可以肯定的是,您的程序中的某些代码(在赋值发生之前执行)将显示未定义的行为。这可能包括从数组末尾脱落(例如,访问
x[3]
,其中x
是一个数组或std::vector
包含少于三个元素),使用未初始化的变量取消对空指针的引用
未定义行为的一个重要特性是,影响可能不会立即发生……只有在随后执行的一些完全不相关的代码中发生崩溃
这几乎肯定会发生在您的代码中。您需要从崩溃发生的地方开始反向工作,以找到实际导致问题的以前执行的代码语句(或代码语句)
这就是SO建议提供MCVE的一个原因——删除无关代码的过程可以让你找到真正的原因。如果不这样做,他们有机会帮助你……因为你发布的代码实际上显示了问题。在这种情况下,你没有这样做
在这种情况下,循环的<>代码是罪魁祸首,因为它访问的容器的元素比它的多。 < P> C++实现的供应商往往会花费很多精力来消除标准库的实现中的明显缺陷。因此,问题的实际原因是简单的<代码> STD::STR:ing
赋值是消失的小(大约为零)
几乎可以肯定的是,您的程序中的某些代码(在赋值发生之前执行)将显示未定义的行为。这可能包括从数组末尾脱落(例如,访问x[3]
,其中x
是一个数组或std::vector
包含少于三个元素),使用未初始化的变量取消对空指针的引用
未定义行为的一个重要特性是,影响可能不会立即发生……只有在随后执行的一些完全不相关的代码中发生崩溃
这几乎肯定会发生在您的代码中。您需要从崩溃发生的地方开始反向工作,以找到实际导致问题的以前执行的代码语句(或代码语句)
这就是SO建议提供MCVE的一个原因——删除无关代码的过程可以让你找到真正的原因。如果不这样做,他们有机会帮助你……因为你发布的代码实际上显示了问题。在这种情况下,你没有这样做
在这种情况下,
for
循环是罪魁祸首,因为它访问的容器元素比它所拥有的要多。你能给我们提供最小的、完整的、可编译的代码来复制问题吗?@DavidSchwartz在我所有的SO问题中,我都试图这样做,但当我不知道如何复制它时,我该怎么做这种情况的另一面?在这种情况下,问题绝对不是指向我的错误消息所指的地方-当它超出向量的边界时没有出错…@areuz\u list.at(loop)
而不是\u list[loop]
会立即发现问题。另外,用前导下划线命名变量也不是一个好主意,比如\u list
@PaulMcKenzie-Hmm,很高兴知道,我会尝试一下,也许从现在开始使用。你认为为什么不好?我使用它,因为它与成员变量相反,成员变量有一个trailing下划线。使用at()
作为健全性检查,以确保您没有越界。确定这一点后,请更改回[]
。至于
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::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);
}
void Label::SetText(std::string& _text) {
if (maxsize_ != 0 && _text.length() > maxsize_) _text.resize(maxsize_);
text_ = _text; // THIS?!
size_ = text_.length();
Redraw();
}
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();
};
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_));
for (unsigned int loop = size_; loop < (size_ + _list.size()); loop++)
{
[...] _list[loop] [...]
}
for (unsigned int loop = 0 ; loop < _list.size() ; loop++)
{
[...] _list[loop] [...]
}