简体   繁体   English

反转c中的链表时出现分段错误问题

[英]Segmentation fault issue while reversing linked list in c

#include <stdio.h>
#include <stdlib.h>

struct node {
    int data;
    struct node *next;
};

struct node *insert(struct node *link, int data) {
    if (link == NULL) {
        link = (struct node *)malloc(sizeof(struct node));
        link->data = data;
        link->next = NULL;
    } else {
        struct node *newlink = (struct node *)malloc(sizeof(struct node));

        newlink->data = data;
        newlink->next = link;
        link = newlink;
    }
    return link;
}

void reverse(struct node *link) {
    int i, j = 0;
    int arr1[100], arr2[100];
    struct node *current;
    int count = 0;

    current = link;

    while (current != NULL) {
        arr1[i] = current->data;
        i = i + 1;
        count = count + 1;
        current = current->next;
    }

    printf("\n");
    i = 0;
    j = 0;

    for (i = count - 1; i >= 0; i--) {
        arr2[j] = arr1[i];
        j = j + 1;
    }

    printf("The elements in the linked list are: ");

    for (i = 0; i < count; i++) {
        printf("%d ", arr1[i]);
    }

    printf("The elements in the reversed linked list are: ");

    for (j = 0; j < count; i++) {
        printf("%d ", arr2[j]);
    }
}

void print(struct node *link) {
    struct node *temp = link;

    printf("The elements in the linked list are: ");

    while (temp != NULL) {
        printf("%d ", temp->data);
        temp = temp->next;
    }
}

void main() {
    int value;

    printf("Enter the value:\n");
    scanf("%d", &value);
    struct node *link = NULL;

    link = insert(link, value);
    char ans[3] = "yes";

    while (ans[0] == 'y') {
        printf("Do you want to add another node? Type Yes/No\n");
        scanf("%s", ans);

        if (ans[0] == 'y') {
            printf("Enter the value:\n");
            scanf("%d", &value);
            link = insert(link, value);
        } else {
            reverse(link);
        }
    }
}

Here is the code I wrote to reverse a single linked list in C. I seem to try different combinations of the program but while doing it by array method, I am unable to get rid of the segmentation fault, and hence it doesn't give output. 这是我编写的用于在C中反转单​​个链表的代码。我似乎尝试使用该程序的不同组合,但是通过数组方法进行处理时,我无法摆脱分段错误,因此它没有给出输出。

There are some problems in your code: 您的代码中存在一些问题:

  • i is uninitialized when used in the while loop in function reverse , causing undefined behavior which could explain the segmentation fault . 在函数reverse中的while循环中使用i时, i未被初始化,从而导致无法定义的行为,这可以解释segmentation fault

  • j is not modified in the loop at the end of the reverse function, causing an infinite loop: jreverse函数末尾未在循环中修改,从而导致无限循环:

     for (j = 0; j < count; i++) { printf("%d ", arr2[j]); } 
  • you are not reversing the list, you just print the list contents in reverse order, and assume its length is at most 100 . 您无需反转列表,只需以相反的顺序打印列表内容,并假定其长度最大为100 This is probably not what you are expected to do. 这可能不是您期望的。

  • in function main , the array ans should be made larger to accommodate at least the word yes , and you should prevent scanf() from storing more characters into it than would fit. 在函数main ,应将数组ans增大为至少容纳单词yes ,并且应防止scanf()向其中存储更多字符。 Also reorganize the code to avoid duplication: 还要重新组织代码以避免重复:

     int main(void) { struct node *link = NULL; for (;;) { char ans[80]; int value; printf("Enter the value:\\n"); if (scanf("%d", &value) != 1) break; link = insert(link, value); printf("Do you want to add another node? Type Yes/No\\n"); if (scanf("%79s", ans) != 1 || ans[0] != 'y') { break; } } reverse(link); return 0; } 

Most of the above problems would have been spotted immediately by increasing the compiler warning level (for example gcc -Wall -Werror or clang -Weverything -Werror ). 通过提高编译器警告级别,可以立即发现上述大多数问题(例如gcc -Wall -Werrorclang -Weverything -Werror )。

Here is a simpler version that reads numbers and allocates the list in the same order as you do, inserting each new element before the previous one, then reverses the list and finally prints it. 这是一个更简单的版本,可以读取数字并按照与您相同的顺序分配列表,将每个新元素插入上一个元素之前,然后反转列表并最终打印出来。 As expected, the list is printed in the order of entry. 正如预期的那样,该列表按输入顺序打印。

#include <stdio.h>
#include <stdlib.h>

struct node {
    int data;
    struct node *next;
};

struct node *insert(struct node *head, int data) {
    struct node *newlink = malloc(sizeof(*newlink));
    newlink->data = data;
    newlink->next = head;
    return newlink;
}

struct node *reverse(struct node *link) {
    struct node *prev = NULL;
    while (link) {
        struct node *temp = link->next;
        link->next = prev;
        prev = link;
        link = temp;
    }
    return prev;
}

void print(struct node *link) {
    printf("The elements in the linked list are: ");

    for (struct node *n = link; n; n = n->next) {
        printf("%d ", n->data);
    }
    printf("\n");
}

int main(void) {
    struct node *link = NULL;
    int value;

    printf("Enter the values, end the list with 0:\n");
    while (scanf("%d", &value) == 1 && value != 0) {
        link = insert(link, value);
    }
    link = reverse(link);
    print(link);
    return 0;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM