我目前正在创建一个行星模拟,如果它们相互碰撞,在尝试删除行星时会出现问题,请参阅下面的详细信息。
我目前在从双链接列表中删除元素时出现问题,导致读取访问冲突,并指出其中一个元素“为0xFFFFFFFFFFFFFFFCB”。我对C比较陌生,所以我相信我只是在某处遗漏某些东西。
请注意,如果在没有使用destroy()方法的情况下使用remove()方法,则不会发生错误,只有当destroy()方法与remove()方法一起使用时才会发生错误,并且只会偶尔发生在那。
代码如下:
struct planet *head; //Head of list
struct planet *tail; //Tail of list
struct planet {
//Data
float mass;
struct planet *next;
struct planet *prev;
};
planet *removeTail() {
struct planet* p = tail;
if (tail) {
if (head == tail) {
head = tail = 0;
}
else {
tail = tail->prev;
p->prev = 0;
tail->next = 0;
}
}
return p;
}
planet *removeHead() {
struct planet* p = head;
if (head) {
if (head == tail) {
head = tail = 0;
}
else {
head = head->next;
p->next = 0;
head->prev = 0;
}
}
return p;
}
planet *remove(struct planet* p) {//Breaking the tree
if (p == head) {
removeHead();
}
else if (p == tail) {
removeTail();
}
else {
p->prev->next = p->next;
p->next->prev = p->prev;
}
return p;
}
planet *destroy(struct planet* p) {
if (p) {
if (p != head || p != tail || (!p->next && p->prev)) {
delete p;
printf("Deleted\n");
return 0;
}
else {
printf("Not deleted\n");
return 0;
}
}
}
for (struct planet *p1 = head; p1 != 0; p1 = p1->next)
{
for (struct planet *p3 = head; p3 != 0; p3 = p3->next)
{
//Collision logic
if(p1 != p3){
if(p1->mass >= p3->mass){
destroy(remove(p3)); //Does not cause an error
break;
}else{
destroy(remove(p1)); //Causes the error.
break;
//Deleting p1 here means the for loop can't move on
}
}
}
}
我相信我已经包含了上述所有相关代码,如果您需要任何进一步的信息,请告诉我。我也不知道是什么触发了错误,因为有时模拟可以删除和删除几个节点而没有问题,在其他情况下它只能删除一个。
非常感谢任何建议!
答案 0 :(得分:1)
删除代码可以是单个函数:
planet *remove(struct planet* p)
if (p->prev == NULL) {
head = p->next;
}
else {
p->prev->next = p->next;
}
if (p->next == NULL) {
tail = p->prev;
}
else {
p->next->prev = p->prev;
}
return p;
}
也许在某个地方应该有一个free(p)
。
答案 1 :(得分:0)
这样有一个答案,问题是外部for循环在p3循环中被破坏了。 p1只需要删除,这样就不会破坏循环。