2013-11-17 3 views
0

Я работаю над программой C для назначения в моем классе CS, который успешно компилируется, но при выполнении ошибки возникает ошибка сегментации. Назначение имеет дело с linkedLists; мы должны были использовать методы, описанные и объявленные в файле заголовка с именем linkedlist.h, и реализовать им файл с именем linkedlist.c. Файл testtest.c предоставляется и используется для тестирования метода.Ошибка сегментации при запуске программы 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, поэтому любые изменения должны быть связаны с linklist.c. Спасибо.

+0

очевидно, что вы havent скомпилированы с символами отладки (опция -g). также ваш, вероятно, должен вызвать _createnode_ перед тем _insertSorted_ – amdixon

ответ

0

В функции insertSorted условие if (newNodeIS-> data ...) вызывает разглашение указателя без проверки, что это не NULL, это будет источник ошибки сегментации. попытаться фиксируя, что отчет назад :)

+0

я добавил, если заявление перед newNode-> данные 'если (newNodeIS! = NULL) \t \t \t \t { \t \t \t \t \t если (newNodeIS-> данные> listHeadIS -> данные) \t \t \t \t \t { \t \t \t \t \t \t listHeadIS = newNodeIS; \t \t \t \t \t} \t \t \t \t} 'Но я все еще получаю ошибку сегментации. – user3000964

+0

Обычно этот вид ошибки повторяется по всему коду, попробуйте перебрать его и очистить эту конкретную ошибку, затем запустите ее снова :) – Caesar23

1
  1. структура ListNode * newNodeCN; newNodeCN-> data = inputData; На самом деле нет нового узла

  2. int listLength (struct ListNode * head) - i никогда не инициализируется.

  3. подъязычная FreeList (структура ListNode * голова) - бесплатно, затем разыменования

+0

Я изменил '* newNodeCN;' на 'struct ListNode * newNodeCN = (struct ListNode *) malloc (sizeof (struct ListNode)); и я инициализировал i в listLength до 0. Это фиксировало ошибку сегментации, и теперь программа запускается дальше, а затем удаляет другую ошибку сегментации. Что вы подразумеваете под свободным, а затем разыгрыванием? Разве это не цикл while в freeList? – user3000964

+0

yep, но вы делаете это в неправильном порядке: вы освобождаете() объект (поэтому его больше не существует), затем вы запрашиваете его член head-> next! на самом деле вы делаете это в removeItem(). –

0

первой в функции createNode, и использовать элемент «данные», но не таНос реальную память для newNodeCN ведьма это Тип - это struct ListNode. кроме того, «ошибка сегментации» обычно возникает, когда вы используете ссылку на неправильный адрес памяти (например, указатель u не malloc или адрес из массива и т. д.).

Смежные вопросы