2012-04-23 2 views
-1

я получил Segfault с этим кодом:вина Сегментация по гр реализации связанного списка при добавлении узлов

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <sys/types.h> 
#include <dirent.h> 
#include <unistd.h> 

typedef struct _node 
{ 
    char *buffer;   
    struct _node *next;  
    int node_count;   
} node; 

typedef struct _list 
{ 
    node *head; 
    node *tail; 
} list; 

list *node_list; 

int list_node_lookup(list *l, char *buffer) 
{ 
    node *temp = l->head; 
    while(temp) 
    { 
     if (strcmp(temp->buffer, buffer) == 0) 
     { 
      /* We got it earlier */ 
      temp->node_count++; 

      return 1; 
     } 
     else 
     { 
      temp = temp->next; 
     } 

    } 

    return 0; 
} 

int adding_to_list(list *l, char *buffer) 
{ 
    int ret; 
    char *tmp = (char *)malloc(sizeof(char)*(strlen(buffer) + 1)); 
    node *new_node = (node *)malloc(sizeof(struct _node)); 

    /* Empty list */ 
    if (l->head == NULL) 
    { 
     strcpy(tmp, buffer); 
     new_node->buffer = tmp; 
     new_node->node_count = 0; 
     l->head = l->tail = new_node; 
     l->head->next = NULL; 
    } 
    else 
    { 
     /* The list is not empty */ 
     ret = list_node_lookup(l, buffer); 
     if (ret == 1) 
     { 
      fprintf(stdout, "Got it before\n"); 
     } 
     else 
     { 
      strcpy(tmp, buffer); 
      new_node->buffer = tmp; 
      new_node->node_count = 0; 
      l->tail->next = new_node; 
      l->tail = new_node; 
      new_node->next = NULL; 
      fprintf(stdout, "Adding this cust : %s\n", buffer); 
     } 
    } 

    return 0; 
} 

int main(int argc, char **argv) 
{ 
    FILE *cust; 
    char buf[BUFSIZ]; 
    DIR* cust_dir; 
    struct dirent* input; 

    node_list = (list *) malloc(sizeof(struct _list)); 
    if (node_list == NULL) 
    { 
      return 1; 
    } 
    node_list->head = node_list->tail = NULL; 

    if (NULL == (cust_dir = opendir("cust_dir"))) 
    { 
     return 1; 
    } 
    while ((input = readdir(cust_dir))) 
    { 
      if (!strcmp (input->d_name, ".")) 
       continue; 
      if (!strcmp (input->d_name, "..")) 
       continue; 

      cust = fopen(input->d_name, "r"); 

      while (fgets(buf, BUFSIZ, cust) != NULL) 
      { 
       adding_to_list(node_list, buf); 
      } 
        fclose(cust); 
    } 

    return 0; 
} 

Когда я проверить свой код с директории, содержащей эти два файла (они содержат пустые строки), я получил странный выход и сег.

Я использую этот файл дважды (customers.txt и customers_copy.txt) в том же каталоге:

1 
2 
3 
4 Kristina Chung H Kristina H. Chung Chung, Kristina H. 
5 Paige Chen H Paige H. Chen Chen, Paige H. 
6 Sherri Melton E Sherri E. Melton Melton, Sherri E. 
7 Gretchen Hill I Gretchen I. Hill Hill, Gretchen I. 
8 Karen Puckett U Karen U. Puckett Puckett, Karen U. 
9 Patrick Song O Patrick O. Song Song, Patrick O. 
10 Elsie Hamilton A Elsie A. Hamilton Hamilton, Elsie A. 
11 
12 Hazel Bender E Hazel E. Bender Bender, Hazel E. 
13 

Первые три строки пусты (когда я использую один файл все в порядке, но это несколько файлов я получил segfault).

Благодарим за помощь, чтобы понять, что не так.

+0

После того, как вы прочитали первый файл, вы никогда не закрываете fp cust, прежде чем перейти к следующему файлу, что может вызвать некоторые проблемы. –

+0

@GregBrown: спасибо, я закрыл его, но ничего не изменил. – iPadDevloperJr

+0

Первое, что вам нужно сделать при получении ошибки сегментации, - запустить вашу программу в отладчике. Это поможет вам определить местоположение ошибки, а также позволить вам просматривать переменные, чтобы помочь вам выяснить причину проблемы. –

ответ

1

Когда вы добавляете узел в список (в хвост списка), вы не устанавливаете указатель next этого узла в NULL. Это означает, что в следующий раз, когда вы выполните поиск, вы вызовете strcmp с недействительными указателями. Это само по себе может вызвать ошибку сегментации.

Простое решение - установить next в NULL, как только вы выделите узел.

Кроме того, если узел уже находится в списке, вы назначаете tmp, но никогда не используете его. Это приведет к утечке памяти. Это похоже на комментарий Грега Брауна - вы также пропускаете файловые дескрипторы и дескрипторы файлов (вы никогда не закрываете cust).

[EDIT]

Проблема заключается в том, что вы читаете каталог «cust_dir», так что вы получаете имена файлов, которые находятся в директории (например, «customers.txt»). Затем вы открываете файл без добавления «cust_dir /» в имя файла.

Итак, если случайно вы также имеете файл в текущем каталоге, он работает. Но в остальном cust NULL (потому что input->d_name - это имя файла внутри «cust_dir», а не в текущем каталоге), и затем вы пытаетесь прочитать данные из указателя NULL-файла. Это вызывает ошибку сегментации.

+0

Спасибо, но ничего не изменилось после добавления new_node-> next = NULL; – iPadDevloperJr

+0

@iPadDevloperJr Вы вызываете 'fclose' с' input', но вы должны вызывать 'cust'. Это также вызывает ошибку сегментации. –

+0

спасибо, что это опечатка. – iPadDevloperJr

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