C Doublely Linked List读取访问冲突

时间:2017-01-06 07:24:52

标签: c

我目前正在创建一个行星模拟,如果它们相互碰撞,在尝试删除行星时会出现问题,请参阅下面的详细信息。

我目前在从双链接列表中删除元素时出现问题,导致读取访问冲突,并指出其中一个元素“为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
                 } 
            }
        }
}

我相信我已经包含了上述所有相关代码,如果您需要任何进一步的信息,请告诉我。我也不知道是什么触发了错误,因为有时模拟可以删除和删除几个节点而没有问题,在其他情况下它只能删除一个。

非常感谢任何建议!

2 个答案:

答案 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只需要删除,这样就不会破坏循环。