繁体   English   中英

运行C程序时出现分段错误

[英]Segmentation fault when running C program

我一直在为CS类中的分配编写C程序,该程序可以成功编译,但是在运行时会出现分段错误错误。 分配处理链表; 我们必须采用描述在头文件linkedlist.h中并声明的方法,并将其实现为文件名为linkedlist.c的文件。 提供了一个名为listtest.c的文件,该文件用于测试该方法。

我的代码(linkedlist.c,注释来自给出的头文件,描述了方法的工作原理):

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


/* Alloc a new node with given data. */
struct ListNode* createNode(int inputData)
{

    struct ListNode *newNodeCN;
    newNodeCN->data = inputData;
    return newNodeCN;
}

/* Insert data at appropriate place in a sorted list, return new list head. */
struct ListNode* insertSorted(struct ListNode* head, int inputData)
{
    printf("insertsorted started \n");

    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)
{
    struct ListNode * tempRem = *headRef;
    int filterVal = data;

    while (tempRem->next != NULL)
    {
        if (tempRem->data == filterVal)
        {
            free(tempRem);
            tempRem = tempRem->next;
            return 1;
        }
    }


    return 0;
}
/* Insert data at head of list, return new list head. */
struct ListNode* push(struct ListNode* head, int data)
{
    printf("push started \n");
    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 pop(struct ListNode** headRef)
{
    struct ListNode * tempPop = *headRef;
    int tempData;

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

    return tempData;
}
/* Return length of the list. */
int listLength(struct ListNode* head)
{
    int i;
    while (head->next != NULL)
    {
        i++;
        head = head->next;
    }
    return i;
}
/* Print list data on single line, separated with spaces. */
void printList(struct ListNode* head)
{
    printf("PrintList Started \n");
    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)
{
    while (head != NULL)
    {
        free(head);
        head = head->next;
    }
}
/* 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;
   }

}

来自listtest.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);
    printf("sort succesful /n");
    stack = push(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", pop(&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;
}

根据Valgrind和GDB的说法,分割错误是由主要原因引起的。 Valgrind给我错误:

 Access not within mapped region at address 0x6FFFFFFE3
==6300==    at 0x400953: main 

我的问题是究竟是什么导致分段错误,我该如何解决,代码中的其他任何内容都可能导致分段错误? 我不允许编辑listtest.c,因此任何更改都必须在linkedlist.c中。 谢谢。

  1. struct ListNode * newNodeCN; newNodeCN-> data = inputData; 实际上没有分配新节点

  2. int listLength(struct ListNode * head)-我从未初始化。

  3. oid freeList(struct ListNode * head)-自由,然后取消引用

在insertSorted函数中,条件if(newNodeIS-> data ...)在没有验证其不是NULL的情况下取消对指针的引用,这是分段错误的根源。 尝试修复该报告:)

首先在函数createNode中,u使用元素“ data”,但没有为newNodeCN分配真正的内存,即类型为struct ListNode。 此外,当您要引用错误的内存地址(例如,指针不是malloc或数组外的地址等等)时,通常会出现“分段错误”。

暂无
暂无

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

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