2016-07-12 2 views
-2

저는 C에서 비교적 새롭고 링크 된 목록이 포함 된 프로그램을 만들고있었습니다. 다음은 매우 간략화 된 코드 버전입니다. C : 링크 된 목록에 대해 변수가 초기화되지 않았습니다.

#include <string.h> 
#include <stdio.h> 
#include <stdlib.h> 

#define STRLEN 100 

struct Gene { 
    int num[4]; 
    struct Gene *next; 
    }; 
typedef struct Gene item; 

void build_list(item *current, item *head, FILE *in); 

int main() { 

    FILE *input; 
    FILE *output; 
    input = fopen("test.data", "r"); 
    output = fopen("test.out", "w+"); 

    item *curr; 
    item *head; 
    head = NULL; 
    int i; 

    build_list(curr, head, input); 
    curr = head; 

    while(curr) { 
     for (i = 0; i < 4; ++i) 
      fprintf(output, "%d\n", curr->num[i]); 
     curr = curr->next; 
     } 

    fclose(input); 
    fclose(output); 
    free(curr); 
} 

void build_list(item *current, item *head, FILE *in) { 

    char gene[STRLEN]; 
    char *tok; 
    char gene_name[STRLEN]; 
    char *search = ","; 
    int j; 

    while (fgets(gene, sizeof(gene), in)) { 

     current = (item *)malloc(sizeof(item)); 
     tok = strtok(gene, search); 
     strcpy(gene_name, tok); 
     for (j = 0; j < 4; ++j) { 
      tok = strtok(NULL, search); 
      current->num[j] = atoi(tok); 
      } 
     current->next = head; 
     head = current; 
    } 
} 

나는 이것을 컴파일하려고

, 그것은 변수 curr가 초기화되지 않은 말한다,하지만 난 malloc로 초기화하더라도 그것은 세그먼트 오류를 ​​던져, 또는 전혀 아무것도를 출력하지 않습니다. 왜 이럴 수 있니?

+0

'build_list (curr, head, input)'이 초기화되지 않은 값을 첫 번째 매개 변수로 전달한다는 사실을 알고 계십니까? – immibis

+0

'curr'과'head'가 값에 의해 전달됩니다 .... –

+0

예, 어떻게이 문제를 해결할 수 있습니까? – matnnar

답변

0

@Sourav Ghosh는 이미 코드에 무엇이 잘못되었는지 설명하고이를 해결하는 방법을 제안했습니다. 다른 방법이 있습니다.

currenthead을 함수 내에서 (즉 포인터에 대한 포인터로) 변경할 변수로 전달하는 대신 함수 반환 값을 사용하는 것이 좋습니다. 그런 식으로 포인터를 포인터로 사용할 필요가 없습니다. 같은

뭔가 :

item* add_item(item* head) 
{ 
    // Place a new item in front 
    item* current = malloc(sizeof(item)); 
    current->next = head; 
    return current; 
} 

item* build_list(item* head, FILE *in) { 

    char gene[STRLEN]; 
    char *tok; 
    char gene_name[STRLEN]; 
    char *search = ","; 
    int j; 

    while (fgets(gene, sizeof(gene), in)) 
    { 
     // Get a new item 
     head = add_item(head); 

     // Fill data into the new item 
     tok = strtok(gene, search); 
     strcpy(gene_name, tok); 
     for (j = 0; j < 4; ++j) 
     { 
      tok = strtok(NULL, search); 
      head->num[j] = atoi(tok); 
     } 
    } 

    return head; 
} 

main에서

이 좋아 호출 :

head = NULL; 
head = build_list(head, input); 

참고 : 가독성을 위해, 나는 malloc 실패에 대한 모든 검사를 건너 뜁니다. 실제 코드에서는 항상 malloc이 NULL을 반환했는지 확인해야합니다.

2

C는 함수 인수 전달에 값을 전달합니다. 따라서 build_list(curr, head, input);으로 전화하면 currhead 그 자체가 값으로 전달되고 해당 변수 (해당 매개 변수)에 대한 변경 사항은 호출자에게 다시 반영되지 않습니다.

따라서, 발신자에

while(curr) 

undefined behavior를 호출 초기화되지 변수 (meeory)에 액세스한다.

currhead을 직접 변경해야하는 경우 주소를 전달하고 기능 내에서 변경해야합니다.

build_list(&curr, &head, input); 

void build_list(item **current, item **head, FILE *in) 

*current = malloc(sizeof(item)); 

같은 무언가가 당신을 위해 일을 얻을 수 있습니다.

+0

나는 당신이 추천 한대로했는데 'member reference base type'item ('struct Gene *'라고도 함)과 같은 구조체 또는 공용체가 아니라는 오류가 발생했습니다. 그리고 여전히 초기화되지 않은 변수에 대해 경고합니다. 무엇이 잘못 되었습니까? – matnnar

+0

@matnnar 죄송합니다. 함수 호출 예제에서 실수를했습니다. 지금 확인하십시오. –

+0

고마워,하지만 여전히 '멤버 참조 기본 유형'항목 ** '('구조체 Gene ** '라고도 함)은 구조체 또는 공용체가 아닙니다. 55 및 57 줄에 오류가 있습니다. 내가 어떻게 할 수 있는지 설명해 주시겠습니까? 고쳐? – matnnar

관련 문제