我试着做一个双链接列表,作为一种练习,我遇到了一些奇怪的行为--如果我尝试在列表中间使用insert_before,就像在trooper3和trooper4中看到的那样,当我尝试从头到尾检查所有元素时,trooper4并没有出现。反向迭代显示所有元素确实都在那里。我应该指出,我只是在学习c++,很可能错过了一些东西。
我在gdb中运行了几次代码,并观察到以下内容:下一个和以前的指针只在第二个for循环期间更新。当我尝试从头到尾迭代时,trooper2的下一个指针直接指向trooper3。
#include<cstdio>
struct Element{
Element* next{};
Element* previous{};
void insert_after(Element* new_element) {
new_element->previous = this;
new_element->next = this->next;
this->next = new_element;
}
void insert_before(Element* new_element) {
new_element->previous = this->previous;
new_element->next = this;
this->previous = new_element;
}
char prefix[2];
short operating_number;
};
int main() {
Element trooper1, trooper2, trooper3, trooper4, trooper5;
trooper1.prefix[0] = 'T';
trooper1.prefix[1] = 'K';
trooper1.operating_number = 421;
trooper1.insert_before(&trooper5);
trooper5.prefix[0] = 'X';
trooper5.prefix[1] = 'X';
trooper5.operating_number = 6767;
trooper1.insert_after(&trooper2);
trooper2.prefix[0] = 'F';
trooper2.prefix[1] = 'N';
trooper2.operating_number = 2187;
trooper2.insert_after(&trooper3);
trooper3.prefix[0] = 'L';
trooper3.prefix[1] = 'S';
trooper3.operating_number = 005;
trooper3.insert_before(&trooper4);
trooper4.prefix[0] = 'Y';
trooper4.prefix[1] = 'Q';
trooper4.operating_number = 768;
printf("going forward\n");
for (Element *cursor = &trooper5; cursor; cursor = cursor->next) {
printf("stormtrooper %c%c-%d\n",
cursor->prefix[0],
cursor->prefix[1],
cursor->operating_number);
}
printf("going back\n");
for (Element *cursor = &trooper3; cursor; cursor = cursor->previous) {
printf("stormtrooper %c%c-%d\n",
cursor->prefix[0],
cursor->prefix[1],
cursor->operating_number);
}
}所以,实际输出是
going forward
stormtrooper XX-6767
stormtrooper TK-421
stormtrooper FN-2187
stormtrooper LS-5
going back
stormtrooper LS-5
stormtrooper YQ-768
stormtrooper FN-2187
stormtrooper TK-421
stormtrooper XX-6767而在前进之后的那一节应该是
stormtrooper XX-6767
stormtrooper TK-421
stormtrooper FN-2187
stormtrooper YQ-768
stormtrooper LS-5UPDATE I根据建议修改了我的代码,现在这些方法如下所示:
void insert_after(Element* new_element) {
new_element->previous = this;
new_element->next = this->next;
this->next->previous = new_element;
this->next = new_element;
}
void insert_before(Element* new_element) {
new_element->previous = this->previous;
new_element->next = this;
this->previous->next = new_element;
this->previous = new_element;
}完全解决了问题。
发布于 2019-10-11 09:04:17
这是因为你忘记了一个链接,当你必须做4个链接时,你只做3个链接。
看下面你错过了什么:
void insert_after(Element* new_element) {
new_element->previous = this;
new_element->next = this->next;
this->next->previous = new_element; // You missed it
this->next = new_element;
}
void insert_before(Element* new_element) {
new_element->previous = this->previous;
new_element->next = this;
this->previous->next = new_element; // You missed it
this->previous = new_element;
}编辑:
我忘记提到,这解决了元素“消失”的问题。
但是..。函数不处理列表为空或只包含一个元素的特殊情况。访问未分配元素(或超出范围的元素)的是未定义的行为,您可能会在某个时候出现分段错误。
https://stackoverflow.com/questions/58337526
复制相似问题