合并两个链表产生段错误等
Merging two linked lists yielding seg faults, etc
我正在创建一个状态对象的链表,每个状态对象都包含一个生活在该状态的常驻对象的链表。用户读入一个数据库文件,然后可以从一些命令中进行选择,例如寻找一个人、移动一个人,或者将两个状态合并为一个全新的状态。当我尝试合并两个州的居民时,我必须创建一个新州,将所有居民从第一个州的居民列表移至新州的居民列表,并对第二个州的居民列表执行相同操作。这些人应该出现在新州的居民名单中,但不会出现在原州的居民名单中。我遇到了一堆错误:当我尝试合并时,我收到重复的空闲块警告;当用户尝试打印出新州的居民名单作为命令时,没有人被列出;此外,当用户尝试打印任一原始状态的居民列表时,前几个会被打印出来,但随后出现设置错误,核心被转储,程序停止 运行。任何帮助将不胜感激。
在我的列表对象中:
void addLink (Link <type> * data) {
if (first == NULL) {
first = data;
last = data;
}
else {
last->next = data;
last = data;
}
}
而在我的主要任务中,如果键入的命令是 "merge"...
else if (cmd == "merge") {
string state1, state2, newstate;
cin >> state1 >> state2 >> newstate;
State * ns = state_ls->addLink(new State(newstate))->data;
Link <State*> * s1 = searchList(state1, state_ls);
Link <State*> * s2 = searchList(state2, state_ls);
List <Person*> people1 = s1->data->res_list;
List <Person*> people2 = s2->data->res_list;
List <Person*> newres_list = ns->res_list;
Link <Person*> * temp = people1.first;
while (temp != NULL) {
newres_list.addLink(temp);
temp = temp->next;
}
temp = people2.first;
while (temp != NULL) {
newres_list.addLink(temp);
temp = temp->next;
}
}
您的代码中的一些问题可能会导致您的问题:
- 您没有检查
searchList()
的结果。如果您输入的状态不存在并且它 returns NULL 怎么办?同样对于 addLink()
如果它可以失败。
people1
、people2
和 newres_list
是原始列表的副本。根据这些 类 的实施方式,这可能很糟糕或非常糟糕。您可能想在这里使用指针或引用,例如:
List <Person*>& people1 = s1->data->res_list;
List <Person*>& people2 = s2->data->res_list;
List <Person*>& newres_list = ns->res_list;
如果您希望将人员从原始状态移动到新状态,您需要在移动后重置人员列表 head/tail。可能是这样的:
s1->person->data->res_list->first = NULL;
s1->person->data->res_list->last = NULL;
s2->person->data->res_list->first = NULL;
s2->person->data->res_list->last = NULL;
Update -- 您似乎对来自多个列表的链表指针和 adding/removing 节点有点困惑。如果我们看一个简单的例子:
List<Person*>* Person1 = new List<Person*>;
List<Person*>* Person2 = new List<Person*>;
List<Person*> List1;
List<Person*> List2;
List1.addLink(Person1);
List1.addLink(Person2); //Ok: List1 has two persons
List2.addLink(Person1); //Error: Person1 can't belong to both lists
一切正常,直到您尝试将一个列表中已有的节点添加到另一个列表中。这将 "mess up" 您的节点 next
指向两个列表。
另一个困惑似乎是如何将所有元素从一个列表移动到另一个列表。您所要做的就是设置两个列表的 head/tail,例如将所有节点从 List1 移动到 List2 只需执行:
List2.first = List1.first;
List2.last = List1.last;
List1.first = NULL;
List1.last = NULL;
您不需要触摸 List1 中的各个节点,因为您没有更改它们的指针位置。如果您想将所有节点从 List1 复制到 List2,则有点不同,因为您必须创建新节点。
如果您对更正后的代码仍有问题,我建议将其简化为一个展示问题的小示例和 post 另一个 SO 问题。
我正在创建一个状态对象的链表,每个状态对象都包含一个生活在该状态的常驻对象的链表。用户读入一个数据库文件,然后可以从一些命令中进行选择,例如寻找一个人、移动一个人,或者将两个状态合并为一个全新的状态。当我尝试合并两个州的居民时,我必须创建一个新州,将所有居民从第一个州的居民列表移至新州的居民列表,并对第二个州的居民列表执行相同操作。这些人应该出现在新州的居民名单中,但不会出现在原州的居民名单中。我遇到了一堆错误:当我尝试合并时,我收到重复的空闲块警告;当用户尝试打印出新州的居民名单作为命令时,没有人被列出;此外,当用户尝试打印任一原始状态的居民列表时,前几个会被打印出来,但随后出现设置错误,核心被转储,程序停止 运行。任何帮助将不胜感激。
在我的列表对象中:
void addLink (Link <type> * data) {
if (first == NULL) {
first = data;
last = data;
}
else {
last->next = data;
last = data;
}
}
而在我的主要任务中,如果键入的命令是 "merge"...
else if (cmd == "merge") {
string state1, state2, newstate;
cin >> state1 >> state2 >> newstate;
State * ns = state_ls->addLink(new State(newstate))->data;
Link <State*> * s1 = searchList(state1, state_ls);
Link <State*> * s2 = searchList(state2, state_ls);
List <Person*> people1 = s1->data->res_list;
List <Person*> people2 = s2->data->res_list;
List <Person*> newres_list = ns->res_list;
Link <Person*> * temp = people1.first;
while (temp != NULL) {
newres_list.addLink(temp);
temp = temp->next;
}
temp = people2.first;
while (temp != NULL) {
newres_list.addLink(temp);
temp = temp->next;
}
}
您的代码中的一些问题可能会导致您的问题:
- 您没有检查
searchList()
的结果。如果您输入的状态不存在并且它 returns NULL 怎么办?同样对于addLink()
如果它可以失败。 people1
、people2
和newres_list
是原始列表的副本。根据这些 类 的实施方式,这可能很糟糕或非常糟糕。您可能想在这里使用指针或引用,例如:List <Person*>& people1 = s1->data->res_list; List <Person*>& people2 = s2->data->res_list; List <Person*>& newres_list = ns->res_list;
如果您希望将人员从原始状态移动到新状态,您需要在移动后重置人员列表 head/tail。可能是这样的:
s1->person->data->res_list->first = NULL; s1->person->data->res_list->last = NULL; s2->person->data->res_list->first = NULL; s2->person->data->res_list->last = NULL;
Update -- 您似乎对来自多个列表的链表指针和 adding/removing 节点有点困惑。如果我们看一个简单的例子:
List<Person*>* Person1 = new List<Person*>;
List<Person*>* Person2 = new List<Person*>;
List<Person*> List1;
List<Person*> List2;
List1.addLink(Person1);
List1.addLink(Person2); //Ok: List1 has two persons
List2.addLink(Person1); //Error: Person1 can't belong to both lists
一切正常,直到您尝试将一个列表中已有的节点添加到另一个列表中。这将 "mess up" 您的节点 next
指向两个列表。
另一个困惑似乎是如何将所有元素从一个列表移动到另一个列表。您所要做的就是设置两个列表的 head/tail,例如将所有节点从 List1 移动到 List2 只需执行:
List2.first = List1.first;
List2.last = List1.last;
List1.first = NULL;
List1.last = NULL;
您不需要触摸 List1 中的各个节点,因为您没有更改它们的指针位置。如果您想将所有节点从 List1 复制到 List2,则有点不同,因为您必须创建新节点。
如果您对更正后的代码仍有问题,我建议将其简化为一个展示问题的小示例和 post 另一个 SO 问题。