int printRev(void *l)
{
list_sll *list= (list_sll *)l;
int i= list->noOfNodes-1;
node_sll *subject= malloc(sizeof(node_sll));
subject->next= list->start;
node_sll *front= NULL; /*node directly in front of subject*/
do {
while(subject->next!=front)
subject= subject->next;
printf("%d. %d\n", i, subject->data);
front= subject;
subject->next= list->start;
--i;
}
while(front!=list->start);
subject= NULL;
free(subject);
return 0;
}
我将用于存储链接列表(已创建)所需详细信息的结构地址(定义如下)传递给 printRev() 函数,该函数接受它作为指向 void 的指针。 这是最小的可行代码:
#include<stdio.h>
#include<stdlib.h>
typedef struct node_sll
{
int data;
struct node_sll *next;
} node_sll;
typedef struct list_sll
{
struct node_sll *start;
int noOfNodes;
} list_sll;
int printlist(void *);
int printRev(void *);
int insert(void *, int);
int main(void)
{
list_sll list1;
list1.noOfNodes= 1;
printf("Creating the first node\nEnter the data\n");
int d;
scanf("%d", &d);
node_sll node1;
node1.data= d;
node1.next= NULL;
list1.start= &node1;
int choice;
do {
printf( "\nEnter:\n1. INSERT: to insert the node\n"
"2. PRINT: print the list\n"
"3. PRINT@rev: print the list in reverse order\n"
"0. QUIT: quit this menu\n");
scanf("%d", &choice);
switch(choice) {
case 1:
printf("Enter the node data\n");
insert(&list1, list1.noOfNodes);
break;
case 2:
printlist(&list1);
break;
case 3:
printRev(&list1);
break;
}
}
while(choice);
return 0;
}
int printlist(void *l)
{
struct list_sll *list= (list_sll *)l;
struct node_sll *p= list->start;
int count= 0;
printf("no of nodes: %d\n", list->noOfNodes);
while(p!=NULL && count < list->noOfNodes) {
printf("%d. %d\n", count, p->data);
p=p->next;
++count;
}
return 0;
}
int insert(void *l, int pos)
{
struct list_sll *list= (list_sll *)l;
struct node_sll *current= malloc(sizeof(node_sll));
int n;
scanf("%d", &(current->data));
current->next= list->start;
struct node_sll *prev_node= NULL;
while(pos--) {
prev_node= current->next;
current->next= current->next->next;
}
if(prev_node==NULL)
list->start= current;
else
prev_node->next= current;
++(list->noOfNodes);
printf("No of nodes %d\n", list->noOfNodes);
return 0;
}
int printRev(void *l)
{
list_sll *list= (list_sll *)l;
int i= list->noOfNodes-1;
node_sll *subject= malloc(sizeof(node_sll));
subject->next= list->start;
node_sll *front= NULL; /*node directly in front of subject*/
do {
while(subject->next!=front)
subject= subject->next;
printf("%d. %d\n", i, subject->data);
front= subject;
subject->next= list->start;
--i;
}
while(front!=list->start);
subject= NULL;
free(subject);
return 0;
}
当我调用 printRev( ) 函数时,会打印反向列表,但由于某种我无法弄清楚的原因,列表元素在打印完成后发生了变化。现在所有节点存储相同的数据,该数据等于第一个节点的数据值。当我只更改一些指针时,为什么数据会发生更改? 在尝试调试时,我创建了一个列表(节点 - 10、20、30、40)并在 printRev( ) 中添加了一些代码行:
int printRev(void *l)
{
list_sll *list= (list_sll *)l;
int i= list->noOfNodes-1;
node_sll *subject= malloc(sizeof(node_sll));
subject->next= list->start;
node_sll *front= NULL; /*node directly in front of subject*/
do {
while(subject->next!=front)
subject= subject->next;
printf("%d. %d\n", i, subject->data);
//printing current list status
printf("%d", list->start->data);
printf("%d", list->start->next->data);
printf("%d", list->start->next->next->data);
printf("%d", list->start->next->next->next->data);
front= subject;
subject->next= list->start;
--i;
}
while(front!=list->start);
subject= NULL;
free(subject);
return 0;
}
这是我调用此函数时得到的输出:
3.40
10
20
30
402.30
10
20
30
401.20
10
20
30
100.10
10
20
10
20
我无法找出问题所在。请帮忙。
最佳答案
对于初学者来说,该函数已经具有未定义的行为,因为它具有返回类型 int
但不返回任何内容。
不需要动态分配节点subject
。可以将其声明为结构体类型的对象。
如果列表为空,这个 do-while 循环也可能导致未定义的行为
do {
while(subject->next!=front)
subject= subject->next;
printf("%d. %d\n", i, subject->data);
//...
}
while(front!=list->start);
因为将尝试访问空指针的值。
此外,在这个 do-while 循环中,指针subject
也发生了变化
do {
while(subject->next!=front)
subject= subject->next;
// ...
subject->next= list->start;
// ...
}
因此原始列表也发生了变化。
这些陈述
subject= NULL;
free(subject);
由于指针subject
指向的原始动态分配对象没有被释放,导致内存泄漏。
如果使用您的方法,那么该函数可以如下所示(无需测试)。
void printRev( void *l )
{
list_sll *list = ( list_sll * )l;
int i = list->noOfNodes;
node_sll subject = { 0, list->start };
node_sll *front = NULL; /*node directly in front of subject*/
while ( i != 0 )
{
node_sll *current = &subject;
while ( current->next != front ) current = current->next;
--i;
printf( "%d. %d\n", i, current->data );
front = current;
}
}
关于c - 为什么这段用于反向打印单向链表的代码段没有按预期工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42890110/