尝试遍历双链表时出现分段错误

时间:2015-12-29 11:11:09

标签: c linked-list segmentation-fault

这是我正在使用的代码:

#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指针)我得到错误,因为我无法访问该特定的内存块。
一旦我完全遍历了链接列表的最后一个节点,我究竟能再次访问它吗?

3 个答案:

答案 0 :(得分: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指向何种类型。

答案 1 :(得分:2)

问题在于您的循环,在解除引用之前,您不会检查temp->next是否为NULL。当循环到达列表的末尾时,temp->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分配内存。您只需使用临时指针变量进行交换。

答案 2 :(得分:1)

嗯,您的程序存在许多问题(特别是在排序功能中)。

首先,考虑到你是循环中的最后一个元素。

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->next;将导致temp为NULL。在此之后提到温度本身就是个问题。

解决方案:检查temp-&gt; 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()