链表列错误。 C

时间:2016-11-12 23:31:14

标签: c segmentation-fault

我必须编写这个创建链表的代码。以下代码如下。问题是我在代码中的某个地方发生了分区,我无法弄清楚在哪里。如果有人能帮助我找到并理解(这是最重要的部分)segfault的来源,我们将不胜感激。

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


/* Alloc a new node with given data. */
struct ListNode* createNode(int data) {
    struct ListNode *new_node = (struct ListNode *)malloc(sizeof(struct ListNode));
    new_node->data = data;
    new_node->next = NULL;
    return new_node;
}

/* Insert data at appropriate place in a sorted list, return new list head. */
struct ListNode* insertSorted(struct ListNode* head, int inputData)
{

    struct ListNode * nextIS = NULL;
    struct ListNode * newNodeIS = NULL;
    struct ListNode * currIS = head;
    struct ListNode * listHeadIS = currIS;
    if (currIS == NULL)
    {
        listHeadIS = createNode(inputData);
        return listHeadIS;
    }
    while (currIS->next != NULL)
    {
        nextIS = currIS->next;

        if (currIS->data < inputData)
        {
            if (nextIS->data >= inputData)
            {

                nextIS->next = createNode(inputData);
                newNodeIS = nextIS->next;
                if (newNodeIS->data > listHeadIS->data)
                {
                    listHeadIS = newNodeIS;
                }
            }
        }
        currIS = currIS->next;
    }

    return listHeadIS;
}
/* Remove data from list pointed to by headRef, changing head if necessary.
 * Make no assumptions as to whether the list is sorted.
 * Memory for removed node should be freed.
 * Return 1 if data was present, 0 if not found. */
int removeItem(struct ListNode** headRef, int data)
{
    while (*headRef && (*headRef)->data != data)
        headRef = &(*headRef)->next;

    if (*headRef)
    {
        struct ListNode *tmp = *headRef;
        free(tmp);
        *headRef = tmp->next;

        return 1;
    }
    return 0;
}

/* Insert data at head of list, return new list head. */
struct ListNode* pushStack(struct ListNode* head, int data)
{
    int dataPush = data;

    struct ListNode * tempPush = (struct  ListNode*)malloc(sizeof(struct ListNode));
    tempPush->data = dataPush;
    tempPush->next = head;
    *head = *tempPush;
    return tempPush;
}

/* Remove and return data from head of non-empty list, changing head.
 * Memory for removed node should be freed. */
int popStack(struct ListNode** headRef)
{
    struct ListNode * tempPop = *headRef;
    int tempData;

    free(tempPop);
    tempData = tempPop->data;
    tempPop = tempPop->next;

    return tempData;
}

/* Return length of the list. */
    int listLength(struct ListNode* head)

 {
   int count = 0;
    struct ListNode* current = head;
    while (current != NULL) {
    count++;
    current=current->next;
  }
   return(count);
}

/* Print list data on single line, separated with spaces and ending
 * with newline. */
void printList(struct ListNode* head)
{

    if (head != NULL)
    {

        while (head->next != NULL)
        {

            printf("%d\n", head->data);
            head = head->next;
        }
    }
}
/* Free memory used by the list. */
void freeList(struct ListNode* head)
{
    struct ListNode* tmp;

    while (head != NULL)
    {
        tmp = head;
        head = head->next;
        free(tmp);
    }
}

/* Reverse order of elements in the list */
void reverseList(struct ListNode** headRef)
{
    struct ListNode * origRL = *headRef;
    struct ListNode * nextRL = NULL;
    struct ListNode * prevRL = NULL;
    while (origRL->next != NULL);
    {
        nextRL = origRL->next;
        prevRL = origRL;
        origRL = nextRL;
        origRL->next = prevRL;
   }

}

用于测试它的文件(linkedlist.c)包含在此评论下面。

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

int main(int argc, char** argv)
{
  int i, n;
  struct ListNode* head = NULL;
  struct ListNode* stack = NULL;

  printf("empty list: ");
  printList(head);

  for(i = 0; i < 23; ++i)
  {
    n = (i*17+11) % 23;
    head = insertSorted(head, n);
    stack = pushStack(stack, n);
  }

  printf("filled list: ");
  printList(head);
  printf("list length = %d\n", listLength(head));

  printf("filled stack: ");
  printList(stack);
  printf("stack size = %d\n", listLength(stack));

  for(i = -4; i < 25; i+=4)
  {
    n = removeItem(&head, i);
    if(!n) printf("remove did not find %d\n", i);  
  }

  printf("list after removes: ");
  printList(head);
  printf("list length = %d\n", listLength(head));

  for(i = 0; i < 5; ++i)
  {
    printf("pop: %d\n", popStack(&stack));
  }

  printf("stack after pops: ");
  printList(stack);
  printf("stack size = %d\n", listLength(stack));

  reverseList(&head);
  printf("list after reverse: ");
  printList(head);

  freeList(head);
  head = NULL;

  freeList(stack);
  stack = NULL;

  return 0;
}

预期输出

empty list: 
filled list: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 
list length = 23
filled stack: 17 0 6 12 18 1 7 13 19 2 8 14 20 3 9 15 21 4 10 16 22 5 11 
stack size = 23
remove did not find -4
remove did not find 24
list after removes: 1 2 3 5 6 7 9 10 11 13 14 15 17 18 19 21 22 
list length = 17
pop: 17
pop: 0
pop: 6
pop: 12
pop: 18
stack after pops: 1 7 13 19 2 8 14 20 3 9 15 21 4 10 16 22 5 11 
stack size = 18
list after reverse: 22 21 19 18 17 15 14 13 11 10 9 7 6 5 3 2 1 

1 个答案:

答案 0 :(得分:0)

您的段错误发生在pushStack()函数中。 *head = *tempPush行在这里毫无意义。当您为NULL传入head指针时,会尝试取消引用它,从而导致段错误。您可以删除此行,并删除不必要的变量dataPush。另外,there is no reason to cast the result of malloc(),最好使用您指定的指针作为sizeof()的参数。如果稍后更改了类型,则避免在sizeof()中使用显式类型意味着要记住更新的内容更少。这意味着新的pushStack()函数是:

struct ListNode * pushStack(struct ListNode *head, int data)
{
    struct ListNode *tempPush = malloc(sizeof(*tempPush));
    tempPush->data = data;
    tempPush->next = head;

    return tempPush;
}

您的insertSorted()函数包含错误。我不确定这是哪里;你的功能需要更加复杂,所以我只为你写了一个新功能。同样,您的printList()功能可以简化。我还修改了printList()函数以匹配您提供的预期输出示例:

struct ListNode * insertSorted(struct ListNode *head, int inputData)
{
    struct ListNode *prev = NULL;
    struct ListNode *curr = head;
    struct ListNode *new_node = createNode(inputData);

    while (curr) {
        if (inputData < curr->data) {
            new_node->next = curr;
            if (prev)
                prev->next = new_node;
            return (prev ? head : new_node);
        }
        prev = curr;
        curr = curr->next;
    }
    if (head) {
        new_node->next = NULL;
        prev->next = new_node;
    } else {
        head = new_node;
    }

    return head;
}

void printList(struct ListNode *head)
{
    struct ListNode *curr = head;

    while (curr) {
        printf("%d ", curr->data);
        curr = curr->next;
    }
    putchar('\n');
}

通过这些更改,输出开始符合您的预期。您的listLength()功能存在问题,popStack()功能存在问题。还可能存在其他问题。我会让你和这些问题搏斗;我的建议应该让你开始。如果您仍有问题,请发送评论,我会尽力帮助您。