奇怪的向量行为
C++: Strange vector behavior
在为我的作业写代码时,我被一个奇怪的行为卡住了。代码太大,所以虽然没有必要,但我不会发布它。
事情是,当我试图从向量中删除一个对象时,我有一个分割错误。当我试着自己调试它时,我发现了这个:
如果我用下面的代码片段执行我的代码,我的vector为空,然后在第二行出现分段错误(因为vector为空)。
cout << this->adjacencyList.empty() << endl; // yeah, I'm working with graph
cout << *(this->adjacencyList[0]) << endl; // list has pointers
然而,当我删除第二行时,它显示vector不为空,然后继续。空向量的保护无法保持,导致分割错误。
你对这种行为有什么看法吗?如果这一点仍然模糊,我可以将我的完整代码作为编辑发布。提前感谢。
编辑:给那个要求"再多一点"的人。
void Node :: removeEdge (string destination) // removes an edge; edge is a class that contains a pointer to another node and its weight
{
bool deleted = false;
cout << *this << endl; // output stream operator is overloaded for node class and is working properly - shows it's label and edges - no error for an edge
cout << this->adjacencyList.empty() << endl;
// cout << *(this->adjacencyList[0]) << endl; // output stream operator is overloaded for edge class - error for an edge
if (!this->adjacencyList.empty())
{
for (vector <Edge *> :: iterator itr = this->adjacencyList.begin(); itr != this->adjacencyList.end(); ++itr)
{
if (((*itr)->getAdjacent())->getLabel() == destination) // segfault here
{
Edge *temp = *itr;
this->adjacencyList.erase (itr);
delete temp;
deleted = true;
}
}
}
if (!deleted)
throw EDGE_DOES_NOT_EXIST; // one of exceptions declared in enum somewhere in my code
}
第二个编辑:
注意:我不能更改标题(它们是由助手提供的),所以不要要求我更改。
如果你对完整的代码感兴趣,你可以在这里找到
http://pastebin.com/iCYF6hdP - exceptions .h -所有异常
http://pastebin.com/1fcgHGDa - edge .h - edge类声明
http://pastebin.com/C2DD6e3D - edge .cpp - edge类实现
http://pastebin.com/ZNqQ1iHE - node .h -节点类声明
http://pastebin.com/kaVtZ3SH - node .cpp - node类实现
http://pastebin.com/A7Fwsi4m - Network.h - graph类声明
http://pastebin.com/02LX0rjw - Network.cpp - graph类实现
http://pastebin.com/MRMn0Scz - main.cpp -示例main
我猜,存储在vector的第一个元素中的指针是无效的(可能是NULL
?)。
所以在this->adjacencyList[0]
中没有出现分段故障,而在*(some_invalid_pointer)
中出现。
试
Edge* firstEdge = this->adjacencyList[0];
cout << *firstEdge << endl;
来验证。
编辑
如果段错误发生在第一个语句(赋值)中,这意味着this
无效,或者您设法破坏了属于vector
内部的内存。为了验证这一点,我们必须看到处理adjacencyList
的所有代码(我不确定是否有SO人有时间完成这项任务…)
注意
我在removeEdge
中发现了一个bug,这与你的问题没有直接关系。在循环中,使用vector::erase
删除当前元素。这个使当前迭代器之外的所有迭代器无效,所以理论上循环的其余部分是臭名昭著的"未定义行为"(TM)。在这个特定的情况下(假设是一个"正常的"标准库),这不会导致段错误,但你可能会错过一些元素:
如果删除当前元素,则当前迭代器(通常只是指针)将指向下一个元素。然后,循环增量将把它移动到这个元素之后的元素,导致一个元素不被检查。
如果你的代码在其他地方有类似的错误,这可能会导致内存损坏。
提示
如果你正在使用microsoftwinc++,你可以启用检查迭代器(见这里)。这些可能能够在你的代码中发现这类错误。
第二次编辑(响应代码)
你在Node::operator+
中有一个严重的错误。
Node &operator+ (Node &l, Node &r) // merges two nodes - for network merging
{
Node newNode (l.label);
// Doing something
return newNode;
}
这意味着,你返回一个引用到一个局部变量, 永远不要这样做:)…
注意,由于您使用的是指针向量,它们分别管理并在析构函数中释放,因此您不能简单地将签名更改为Node operator+(...
:在这种情况下,将调用标准复制构造函数,它将简单地将所有指针复制到结果对象。然后,调用局部对象的析构函数,使所有指针失效。
为了解决这个问题,你应该在Node
上实现一个复制构造函数,它可以对邻接表中的所有边进行实际复制。
或者,您可以使用智能指针(auto_ptr
resp。unique_ptr
或shared_ptr
)用于列表。
或者您将合并函数更改为类似Node::mergeFrom(Node& node2)
的东西,而不是重载+
操作符。
关于原来的问题,你可以很容易地结束工作无效的Node
实例使用您当前的代码(所以*this
指针将无效的removeEdge
内)
- 写入向量<向量<bool>>
- 函数向量_指针有不同的原型,我可以构建一个吗
- std::向量与传递值的动态数组
- 将值指定给向量(2D)的向量中的某个位置
- 找不到成员对象:没有名为get_event()的成员,也处理多态性和向量
- 如何使用向量的template_back函数
- 尝试通过多个向量访问变量时,向量下标超出范围
- 如何通过派生类函数更改基类中的向量
- C++从另一个类访问公共静态向量的正确方法是什么
- 如何将ampl中的集合表示为c++中的向量
- 变量没有改变?通过向量的函数调用
- 迭代时从向量和内存中删除对象
- 向量 <int> a {N, 0} 和 int arr a[N] = {0} 的时间复杂度有什么区别
- 如何为模板化对象创建模板向量?VS正在投掷C3203
- 计算排序向量的向量中唯一值的计数
- 矩阵向量乘法(cublasDgemv)返回零
- 一对向量构造函数:初始值设定项列表与显式构造
- 将结构向量排序为子组
- 在C++中调整向量中的索引
- 向量元素的引用地址与它所指向的向量元素的地址不同.为什么