插入一个基本的单向链表节点似乎破坏了我的 c++ 代码?
Inserting a basic singly linked list node seems to break my c++ code?
单链表和节点类以及main
函数的开始,我在其中编写了代码功能的简要概述。问题出在main
函数即将结束时。我写了"..."代替我认为不相关的代码,因为它只是解析字符串并将它们分配给string temp_hold[3]
数组。
#include <bits/stdc++.h>
using namespace std;
class Node {
public:
string value;
string attr;
string tagname;
Node *next;
Node(string c_tagname, string c_attr, string c_value) {
this->attr = c_attr;
this->value = c_value;
this->tagname = c_tagname;
this->next = nullptr;
}
};
class SinglyLinkedList {
public:
Node *head;
Node *tail;
SinglyLinkedList() {
this->head = nullptr;
this->tail = nullptr;
}
void insert_node(string c_tagname, string c_attr,string c_value) {
Node *node = new Node(c_tagname,c_attr, c_value);
if (!this->head) {
this->head = node;
} else {
this->tail->next = node;
}
this->tail = node;
}
};
int main(int argc, char **argv) {
/* storage is a vector holding pointers to the linked lists
linked lists are created and the linked list iterator sll_itr is incremented when
previous line begins with '</' and the currentline begins with '<'
linked lists have nodes, which have strings corresponding to tagname, value, and attribute
*/
SinglyLinkedList *llist = new SinglyLinkedList();
vector<SinglyLinkedList*> sllVect;
sllVect.push_back(llist);
auto sll_itr = sllVect.begin();
string temp_hold[3];
// to determine new sll creation
bool prev = false;
bool now = false;
//input
int num1, num2;
cin >> num1; cin >> num2;
//read input in
for (int i = 0; i <= num1; ++i) {
string line1, test1;
getline(cin, line1);
test1 = line1.substr(line1.find("<") + 1);
//determine to create a new linked list or wait
if (test1[0] == '/') {
prev = now;
now = true;
} else {
//make a node for the data and add to current linked list
if (i > 0) {
prev = now;
now = false;
//if last statement starts with '</' and current statment starts with '<'
// then start a new sll and increment pointer to vector<SinglyLinkedList*>
if (prev && !now) {
SinglyLinkedList *llisttemp = new SinglyLinkedList();
sllVect.push_back(llisttemp);
sll_itr++;
}
}
//parse strings from line
int j = 0;
vector<string> datastr;
vector<char> data;
char test = test1[j];
while (test) {
if (isspace(test) || test == '>') {
string temp_for_vect(data.begin(),data.end());
if (!temp_for_vect.empty()) {
datastr.push_back(temp_for_vect);
}
data.clear();
} else
if (!isalnum(test)) {
} else {
data.push_back(test);
}
j++;
test = test1[j];
}
//each node has 3 strings to fill
int count = 0;
for (auto itrs = datastr.begin(); itrs!=datastr.end(); ++itrs) {
switch (count) {
case 0:
temp_hold[count]=(*itrs);
break;
case 1:
temp_hold[count]=(*itrs);
break;
case 2:
temp_hold[count]=(*itrs);
break;
default:
break;
}
count++;
}
}
cout << "before storing node" << endl;
(*sll_itr)->insert_node(temp_hold[0], temp_hold[1], temp_hold[2]);
cout << "after" << endl;
}
cout << "AFTER ELSE" << endl;
return 0;
}
这是破坏代码的行。auto sll_itr
被取消引用,这意味着*sll_itr
现在是一个SinglyLinkedList*
,我们可以调用insert_node(string, string, string)
将节点添加到当前链表中。但是,当我保留该行时,else 语句大括号之后的任何内容都不会运行,这意味着cout<<"AFTER ELSE"<< endl;
不会触发。如果我删除insert_node行,则程序运行cout<<"AFTER ELSE"<< endl;
我不确定问题是什么。
(*sll_itr)->insert_node(temp_hold[0],temp_hold[1],temp_hold[2]);
cout << "after" << endl;
} //NOT HANGING. This closes an else statement.
cout << "AFTER ELSE" << endl;
return 0;
}
编译为g++ -o myll mylinkedlist.cpp
然后myll.exe < input.txt
input.txt
包含
8 3
<tag1 value = "HelloWorld">
<tag2 name = "Name2">
</tag2>
</tag1>
<tag5 name = "Name5">
</tag5>
<tag6 name = "Name6">
</tag6>
你的链表不是问题,至少不是这里的问题。
正在制造灾难的秘诀:保留、引用和潜在地操作动态集合上的迭代器,这可能会使容器修改的迭代器失效。您的代码就是这样做的。扔掉所有之间的拐杖:
vector<SinglyLinkedList*> sllVect;
sllVect.push_back(llist);
auto sll_itr = sllVect.begin();
....
SinglyLinkedList *llisttemp = new SinglyLinkedList();
sllVect.push_back(llisttemp); // HERE: INVALIDATES sll_iter on internal resize
sll_itr++; // HERE: NO LONGER GUARANTEED VALID; operator++ CAN INVOKE UB
要解决此问题,您有两种选择:
- 使用不会使push_back上的迭代器失效的容器。实际上只有两个序列容器符合该描述:
std::forward_list
和std::list
。 - 将您的算法更改为按索引引用,而不是通过迭代器引用。 即,让你的循环迭代,直到索引元素到达容器末端,然后中断。
可以在此处找到有关使指针和迭代器无效/不使指针和迭代器失效的容器的精彩讨论。值得一读。
相关文章:
- 创建了一个链表,但如何删除 c++ 中的"所有"节点
- 将树节点添加到向量向量中的 n 元树遍历的平均和最坏情况时间复杂度是多少?
- 插入一个基本的单向链表节点似乎破坏了我的 c++ 代码?
- wxWidgets mac剪贴板在3.1.3上坏了?
- 计时器坏了或者其他什么的
- boost::p rocess::env 在 ubuntu 19.04 上坏了?
- C++链表中出现了垃圾节点
- std::regex 是否保证了最坏情况下的时间复杂度?
- 课堂上的一行,使整个应用程序坏了. 0xC000005错误
- 链接列表的push_front和push_back方法似乎删除了节点
- 链表替换了前面的节点,而不是弹出到后面的节点上
- Dijkstra首个节点访问了
- 嵌套的C 常数数据结构,没有初始化列表或明确命名所有节点-VC 2012过早破坏了内部元素
- SFML sf::Text::setFillColor 坏了,还是我做错了什么
- 开关内的案例不停地循环,即使我坏了
- 删除链表中的节点留下了一些数据
- 溪水变坏了
- 我最基本的c++程序坏了,我不知道为什么
- 我的电脑怎么坏了?
- 条件评估是否优化?这个代码坏了吗