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

标签 c pointers for-loop doubly-linked-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 个成员的结构:一个表示不同元素数据类型的 union ,一个 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;
    }       
}

关于c - 在 for 循环的下一次迭代开始后,指针指向的数据在复制另一个列表末尾的列表时被破坏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51632569/

相关文章:

C初始化总线错误

c - 在结构指针中引用结构指针

c++ - 将数组的原始指针转换为 unique_ptr

c++ - 为什么在使用相似的逻辑递增两种不同的指针类型时会得到不同的地址?

Python循环遍历列表并根据条件追加

javascript - 如何初始化数组变量

css - 是否可以在 lesscss forloop 中放置多个 CSS 规则?

php - Web 应用程序的超快速数据库访问 - SQL 或 NoSQL,解释型 PHP 或编译型 C?

c - 在链表前面插入一个节点

c - 冒泡排序的一个错误