2012-04-23 6 views
-1

를 추가 나는이 코드 세그먼트 폴트를 가지고 : 분할 결함 노드

#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; 
} 

나는이 두 파일을 (그들이 빈 줄을 포함)를 포함 디렉토리 내 코드를 테스트

, 난 이상한 출력과 seg 오류가 발생했습니다.

나는 같은 디렉토리에 두 번 (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을 할당하지만 결코 사용하지 마십시오. 그건 기억이 누출 될거야. 이것은 Greg Brown의 주석과 유사합니다. 파일 설명자와 파일 핸들이 누출되고 있습니다 (결코 닫지 마십시오. cust).

문제는 당신이 디렉토리 (예를 들어, "customers.txt") 파일의 이름을 받고, 그래서 당신은, "cust_dir"디렉토리를 읽는 것입니다

[편집]. 그런 다음 파일 이름에 "cust_dir /"을 추가하지 않고 파일을 엽니 다.

우연히도 현재 디렉토리에 파일이 있으면 작동합니다. 그러나 그렇지 않은 경우 cust은 NULL입니다 (input->d_name은 현재 디렉토리가 아닌 "cust_dir"안에있는 파일의 이름이므로). 그런 다음 NULL 파일 포인터에서 데이터를 읽으려고합니다. 세그먼트 화 오류가 발생합니다.

+0

고맙지 만 new_node-> next = NULL을 추가해도 아무 것도 변경되지 않았습니다. – iPadDevloperJr

+0

@iPadDevloperJr'input'과 함께'fclose'를 호출하지만'cust'로 호출해야합니다. 또한 세분화 오류가 발생합니다. –

+0

감사합니다. 오타입니다. – iPadDevloperJr