【问题标题】:Segmentation fault when trying to traverse a double linked list尝试遍历双链表时出现分段错误
【发布时间】:2015-12-29 11:11:08
【问题描述】:

这是我正在使用的一段代码:

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

int wordlen = 4;
typedef struct Node
{
    char* word;
    struct Node* next;
    struct Node* prev;
}node;
 node* head;

 node * getWord(char* x)
 {
    node* newNode = malloc(sizeof(node));
    newNode->word = x;
    newNode->next = NULL;
    newNode->prev = NULL;
    return newNode;
 }

 void insertion(char* x)
 {
    node* temp = head;
    node* newNode = getWord(x);
    if (head == NULL)
    {
        head = newNode;
        return;
    }
    while(temp->next != NULL) 
    temp = temp->next;
    temp->next = newNode;
    newNode->prev = temp;
 }

 void print()
 {
    node* temp = head;
    while (temp != NULL)
    {
        printf("%s", temp->word);
        temp = temp->next;
        printf(" ");
    }
    printf("\n");
 }

 void sort()
 {
    char* a = malloc((wordlen + 1)*sizeof(char));
    char* b = malloc((wordlen + 1)*sizeof(char));
    node* temp = head;
    while (temp != NULL)
    {
        a = temp->word;
        temp = temp->next;
        b = temp->word;
        if (a[0] < b[0])
        {
            //temp->word = a;
            //temp = temp->prev;
            //temp->word = b;
        }
    }
 }


int main(int argc, char *argv[])
{
    insertion("asdk");
    insertion("mapa");
    insertion("klop");
    sort();
    print();
    return 0;
}

分段错误出现在 sort() 函数中,尤其是在变量 b 中。
我想到的是当指针到达 NULL 时,当我试图返回(使用 prev 指针)我收到错误,因为我无权访问该特定内存块。
一旦我完全遍历了链表的最后一个节点,我该如何再次访问它?

【问题讨论】:

  • 您可以通过维护尾指针和头指针来访问最后一个节点。您甚至可以将它们保存在 node 结构中,这样您就只有一个与列表关联的变量。

标签: c linked-list segmentation-fault


【解决方案1】:

问题是您的循环,您在取消引用之前没有检查temp-&gt;next 是否为NULL。当循环到达列表末尾时,temp-&gt;next 为 NULL。将sortinsertion 中的循环条件更改为:

  void sort()
  {
    char* a;
    char* b;
    node* temp = head;
    while (temp && temp->next != NULL)
    {
        a = temp->word;
        temp = temp->next;
        b = temp->word;
        if (a[0] < b[0])
        {
            temp->word = a;
            temp = temp->prev;
            temp->word = b;
        }
    }
  }

 void insertion(char* x)
 {
    node* temp = head;
    node* newNode = getWord(x);
    if (head == NULL)
    {
        head = newNode;
        return;
    }
    while(temp && temp->next != NULL) 
    temp = temp->next;
    temp->next = newNode;
    newNode->prev = temp;
 }

此外,您不需要为ab 分配内存。您只需使用临时指针变量进行交换即可。

【讨论】:

  • 用这个解决方案我不会丢失指向最后一个节点的指针吗?
  • @Korpel 否。循环“提前”循环一个节点。您在每次迭代中读取两个节点。一个是当前节点,另一个是下一个节点。如果您只有一个节点,则循环不会运行。如果您有 2 个节点,它将运行一次。如果您有 3 个节点,它将运行两次,依此类推。
【解决方案2】:

sort 中有很大的内存泄漏:

char* a = malloc((wordlen + 1)*sizeof(char));
char* b = malloc((wordlen + 1)*sizeof(char));
...
    a = temp->word;        // This leaks a
    ...
    b = temp->word;        // This leaks b

您不能在 C 中分配字符串,您需要使用 strcpy 复制它们。

您还应该测试每个malloc 返回的NULL。请不要乘以sizeof(char),根据 C 标准的定义,它是 1。如果要相乘,请使用sizeof(*a),这始终是正确的,无论a 指向什么类型。

【讨论】:

    【解决方案3】:

    嗯,你的程序有很多问题(特别是排序功能)。

    首先,考虑到你在下面的while循环中的最后一个元素。

    while (temp != NULL)
        {
            a = temp->word;
            temp = temp->next;
            b = temp->word;
            if (a[0] < b[0])
            {
                //temp->word = a;
                //temp = temp->prev;
                //temp->word = b;
            }
        }
     }
    

    当对最后一个节点执行循环时,这一行temp = temp-&gt;next; 将导致 temp 为 NULL。之后推迟 temp 本身就是有问题的。

    解决方案:检查 temp->next !=NULl 而不是 temp==NULL。

    第二,你是在分配内存而不是释放它。

    char* a = malloc((wordlen + 1)*sizeof(char));
    char* b = malloc((wordlen + 1)*sizeof(char));
    

    解决方案:释放此内存。

    第三,C不支持复制字符串的方式。

     a = temp->word;
     b = temp->word;
    

    解决方法:使用strcpy()

    【讨论】:

      猜你喜欢
      • 2017-11-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-22
      • 1970-01-01
      相关资源
      最近更新 更多