在 for 循环的下一次迭代开始后,指针指向的数据在复制另一个列表末尾的列表时被破坏

The data pointed to by a pointer gets corrupted just after the start of the next iteration of a for loop in copying a list at the end of another list

我正在编写函数 void joinList(List *l1, List *l2) 的代码,它将 l1 指向的双向链表复制到 l2 指向的双向链表的末尾,更改l2指向的列表,并保持l1指向的列表不变。如果 l1 指向 5, 9, 14l2 指向 2, 7,那么在调用两个列表上的函数后 l2 必须指向 2, 7, 5, 9, 14l1 仍然指向 5, 9, 14.

任一列表中的每个节点都是一个具有 3 个成员的结构:一个表示不同元素数据类型的联合,一个 prev 和一个 next 指针。

列表本身是一个有 4 个成员的结构:一个指向第一个节点的 head 指针,一个指向最后插入或删除节点之前的节点的 current 指针, curPos 用于保存 current 指向的节点的索引和 size 用于存储列表的大小。

列表的实现在插入、删除、遍历、销毁等方面完美无缺。

typedef union type {
    int intElement;
    double doubleElement;
    char charElement;
} listEntry;

typedef struct node {
    listEntry element;
    struct node *next;
    struct node *prev;
} listNode;

typedef struct list {
    listNode *head;
    listNode *current;
    int size;
    int curPos;
} List;

void initializeList(List *);
void joinList(List *, List *);

关于函数的定义

void joinList(List *l1, List *l2) {
    listNode *slider = l1->head;
    listNode *nodePtr = malloc(sizeof(listNode));

    for (int s = 0; s < l1->size; s++) {
        printf("l2->current->next %lf\n", l2->current->next->element.doubleElement);
        *nodePtr = *(slider);

        if (!l2->size) {
            //for empty l2
            nodePtr->next = l2->current;
            l2->head = nodePtr;
            nodePtr->prev = l2->current;
            l2->current = nodePtr;
        } else
        if (l2->size == 1) {
            //for one-node l2
            nodePtr->next = NULL;
            nodePtr->prev = l2->current;
            l2->current->next = nodePtr;
        } else {
            //general case
            nodePtr->next = NULL;
            nodePtr->prev = l2->current->next;
            l2->current->next->next = nodePtr;
            l2->current = l2->current->next;
        }

        l2->size++;
        slider = slider->next;
        printf("l2->current->next %lf\n", l2->current->next->element.doubleElement);
    }       
}

在用 2 个列表调用函数时。 循环中的最后一行打印 l2->current->next 指向我想要的正确数据,但是在开始循环的下一次迭代之后,该指针指向的数据被损坏,如 printf 所示循环开头的语句。请注意,在这两种情况下,指针仍然持有相同的地址。是否有可能循环仅通过迭代更改数据?

您正在为附加到目标列表的每个元素重新使用相同的 listNode 结构。您必须为您复制的每个元素分配一个新元素。此外,没有理由特例 l2->size == 1.

void joinList(List *l1, List *l2) {
    listNode *nodePtr;
    listNode *slider = l1->head;

    for (int s = 0; s < l1->size; s++) {
        nodePtr = malloc(sizeof(listNode));
        if (nodePtr == NULL) {
            printf("memory allocation failure\n");
            return;
        }
        *nodePtr = *slider;
        nodePtr->next = NULL;
        nodePtr->prev = NULL;

        if (!l2->size) {
            //for empty l2
            l2->head = nodePtr;
            l2->current = nodePtr;
        } else {
            //general case
            nodePtr->prev = l2->current;
            l2->current->next = nodePtr;
            l2->current = nodePtr;
        }
        l2->size++;
        slider = slider->next;
    }       
}