双链表反转 - 打印出垃圾数据

时间:2022-09-05 19:55:29

I've got problem with this part of code. My goal is to reverse a doubly linked list. I receive garbage values when I try to print out reversed list.

这部分代码我遇到了问题。我的目标是扭转双重链表。当我尝试打印反向列表时,我收到垃圾值。

typedef struct node{
    int val;
    struct node* prev;
    struct node* next;
}Node;

typedef struct list{
    Node* head;
    Node* tail;
}List;

void pushFront(List* l, Node* node){
    if(l->head == NULL){
        l->head = node;
        l->tail = node;
        l->tail->next = NULL;
    }else{
        l->head->prev = node;
        node->next = l->head;
        l->head = node;
    }
}
void printList(List* list){

    Node *ptr = list->head;
    while(ptr != NULL){
        printf("%i ",ptr->val);
        ptr = ptr->next;
    }
    puts("");
    free(ptr);
}

void reverse(List* lista){

    Node* ptr = lista->head;
    Node* temp = NULL;
    while(ptr != NULL){
        temp = ptr->prev;
        ptr->prev = ptr->next;
        ptr->next = temp;
        ptr = ptr->prev;
    }

    if(temp != NULL)
        lista->head = temp->prev;
    free(ptr);
    free(temp);
}

Output I receive:

我收到的输出:

Original list: 1 2 3 4 5 6 7

原始清单:1 2 3 4 5 6 7

Reversed list: 1 8532616 3 4 5 6 7 8528368 2002618240

反向清单:1 8532616 3 4 5 6 7 8528368 2002618240

2 个解决方案

#1


1  

I guess you use your function printList two times on the same list (once before and once after reversing the list) which leads to undefined behavior as you free your list during printList and then try to access and work with those same memory locations -> do not free your stuff when you are not done with it:

我猜你在同一个列表上使用你的函数printList两次(在反转列表之前和之后一次),这导致在printList期间释放列表时出现未定义的行为,然后尝试访问并使用这些相同的内存位置 - > do当你没有完成它时,不要释放你的东西:

void printList(List* list){

    Node *ptr = list->head;
    while(ptr != NULL){
        printf("%i ",ptr->val);
        ptr = ptr->next;
    }
    puts("");
    // free(ptr); --> Remove this line
}

#2


1  

Why are you freeing the nodes in printList() and reverse()? In C, you should only free variables, which were previously allocated, with malloc() for example. When you declare variables in a C function, it will be automatically allocated to the stack or other memory region (or even in the CPU registers). They will also be automatically freed at the end of your function. If you are dynamically allocating your nodes and then freeing them in your "reverse" function, I would expect to see garbage when you read the freed node. I tried to remove the "free" calls and the code worked fine. https://ideone.com/CN1MaC

为什么要释放printList()和reverse()中的节点?在C中,您应该只使用malloc()释放先前分配的变量。在C函数中声明变量时,它将自动分配给堆栈或其他内存区域(甚至在CPU寄存器中)。它们也将在您的功能结束时自动释放。如果您正在动态分配节点然后在“反向”函数中释放它们,那么当您读取释放的节点时,我希望看到垃圾。我试图删除“免费”调用,代码工作正常。 https://ideone.com/CN1MaC

#include <stdio.h>

typedef struct node{
    int val;
    struct node* prev;
    struct node* next;
}Node;

typedef struct list{
    Node* head;
    Node* tail;
}List;

void pushFront(List* l, Node* node){
    if(l->head == NULL){
        l->head = node;
        l->tail = node;
        l->tail->next = NULL;
    }else{
        l->head->prev = node;
        node->next = l->head;
        l->head = node;
    }
}
void printList(List* list){

    Node *ptr = list->head;
    while(ptr != NULL){
        printf("%i ",ptr->val);
        ptr = ptr->next;
    }
    puts("");
}

void reverse(List* lista){

    Node* ptr = lista->head;
    Node* temp = NULL;
    while(ptr != NULL){
        temp = ptr->prev;
        ptr->prev = ptr->next;
        ptr->next = temp;
        ptr = ptr->prev;
    }

    if(temp != NULL)
        lista->head = temp->prev;
}

int main(void) {
    List list = { NULL, NULL };
    Node nodeArr[7];
    int i;

    for( i = 0; i < 7; i++ )
    {
        nodeArr[i].val = 7 - i;
        nodeArr[i].prev = NULL;
        nodeArr[i].next = NULL;
        pushFront(&list, &nodeArr[i]);
    }

    printList(&list);
    reverse(&list);
    printList(&list);

    // your code goes here
    return 0;
}

Output:

输出:

1 2 3 4 5 6 7 
7 6 5 4 3 2 1 

#1


1  

I guess you use your function printList two times on the same list (once before and once after reversing the list) which leads to undefined behavior as you free your list during printList and then try to access and work with those same memory locations -> do not free your stuff when you are not done with it:

我猜你在同一个列表上使用你的函数printList两次(在反转列表之前和之后一次),这导致在printList期间释放列表时出现未定义的行为,然后尝试访问并使用这些相同的内存位置 - > do当你没有完成它时,不要释放你的东西:

void printList(List* list){

    Node *ptr = list->head;
    while(ptr != NULL){
        printf("%i ",ptr->val);
        ptr = ptr->next;
    }
    puts("");
    // free(ptr); --> Remove this line
}

#2


1  

Why are you freeing the nodes in printList() and reverse()? In C, you should only free variables, which were previously allocated, with malloc() for example. When you declare variables in a C function, it will be automatically allocated to the stack or other memory region (or even in the CPU registers). They will also be automatically freed at the end of your function. If you are dynamically allocating your nodes and then freeing them in your "reverse" function, I would expect to see garbage when you read the freed node. I tried to remove the "free" calls and the code worked fine. https://ideone.com/CN1MaC

为什么要释放printList()和reverse()中的节点?在C中,您应该只使用malloc()释放先前分配的变量。在C函数中声明变量时,它将自动分配给堆栈或其他内存区域(甚至在CPU寄存器中)。它们也将在您的功能结束时自动释放。如果您正在动态分配节点然后在“反向”函数中释放它们,那么当您读取释放的节点时,我希望看到垃圾。我试图删除“免费”调用,代码工作正常。 https://ideone.com/CN1MaC

#include <stdio.h>

typedef struct node{
    int val;
    struct node* prev;
    struct node* next;
}Node;

typedef struct list{
    Node* head;
    Node* tail;
}List;

void pushFront(List* l, Node* node){
    if(l->head == NULL){
        l->head = node;
        l->tail = node;
        l->tail->next = NULL;
    }else{
        l->head->prev = node;
        node->next = l->head;
        l->head = node;
    }
}
void printList(List* list){

    Node *ptr = list->head;
    while(ptr != NULL){
        printf("%i ",ptr->val);
        ptr = ptr->next;
    }
    puts("");
}

void reverse(List* lista){

    Node* ptr = lista->head;
    Node* temp = NULL;
    while(ptr != NULL){
        temp = ptr->prev;
        ptr->prev = ptr->next;
        ptr->next = temp;
        ptr = ptr->prev;
    }

    if(temp != NULL)
        lista->head = temp->prev;
}

int main(void) {
    List list = { NULL, NULL };
    Node nodeArr[7];
    int i;

    for( i = 0; i < 7; i++ )
    {
        nodeArr[i].val = 7 - i;
        nodeArr[i].prev = NULL;
        nodeArr[i].next = NULL;
        pushFront(&list, &nodeArr[i]);
    }

    printList(&list);
    reverse(&list);
    printList(&list);

    // your code goes here
    return 0;
}

Output:

输出:

1 2 3 4 5 6 7 
7 6 5 4 3 2 1