我正在编写函数 void joinList(List *l1, List *l2)
的代码,它将 l1
指向的双向链表复制到l2
指向的双向链表,改变l2
指向的链表,保持l1
指向的链表不变。如果l1
指向5,9,14
,l2
指向2,7
,那么调用函数后在两个列表中,l2
必须指向 2, 7, 5, 9, 14
而 l1
仍然指向 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/