2017-11-10 1 views
1

성 및 이름의 조합 인 jedi 이름을 계산하는 코드를 작성하고 있습니다. 전체 코드를 작성하고 while 루프에서 세그멘테이션 오류를 가져 왔습니다.구조체 포인터로 텍스트 파일을 읽는 중 Segfault

다음은 코드입니다. 당신 때문에 역 참조 name하려고 할 때 '

Structures.h

//void jediName(char *first_name, char *last_name, char buffer[10]); 
//void jediName(struct Names Name_Param); 
//void * allocate(unsigned int size); 
//void * deallocate(void *, int size); 

int heap_usage = 0; 

struct Names{ 
    char *first_name; 
    char *last_name; 
    char *jedi_name; 
}; 

struct Names *name; 

void jediName(struct Names *Name_Param); 
void * allocate(unsigned int size); 
void * deallocate(void *, int size); 

program.c에

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

#include "Structures.h" 

int main(){ 

// char fname[10]; 
// char lname[10]; 
// char buff[10]= ""; 
    char buffer1[250]; 
    char buffer2[250]; 

    FILE * fp; 
/* 
     printf("Enter the first & last name : \n"); 
     scanf("%s %s", buffer1, buffer2); 

    fp = fopen("names.txt", "a"); 
    fprintf(fp, "\n%s %s", buffer1, buffer2); 
    fclose(fp); 
*/ 

    fp = fopen("names.txt","r"); 
    name->first_name == allocate(10); 
    name->last_name == allocate(10); 
    name->jedi_name == allocate(10); 

    while(!feof(fp)){ 
     fscanf(fp, "%s %s", name->first_name, name->last_name); 
     jediName(name); 
//  jediName(name->first_name, name->last_name, name->jedi_name); 
     printf("%s %s %s", name->first_name, name->last_name); 
    } 
    deallocate(name->first_name, 10); 
     deallocate(name->last_name, 10); 
     deallocate(name->jedi_name, 10); 

    fclose(fp); 

    return 0; 
} 

/* 
void jediName(char *first_name, char *last_name, char buffer[10]){ 
    if(strlen(first_name)<2 || strlen(last_name)<3) 
     printf("Name of %s %s is too short to compute a jedi name\n", first_name, last_name); 
    else{ 
     buffer[0] = last_name[0]; 
      buffer[1] = last_name[1]; 
      buffer[2] = last_name[2]; 
      buffer[3] = first_name[0]; 
      buffer[4] = first_name[1]; 
      printf("Jedi Name for %s %s is %s\n", first_name, last_name, buffer); 
    } 

    return; 
} 
*/ 

void jediName(struct Names *Name_Param){ 
     if(strlen(Name_Param->first_name)<2 || strlen(Name_Param->last_name)<3) 
       printf("Name of %s %s is too short to compute a jedi name\n", Name_Param->first_name, Name_Param->last_name); 
     else{ 
       Name_Param->jedi_name[0] = Name_Param->last_name[0]; 
       Name_Param->jedi_name[1] = Name_Param->last_name[1]; 
       Name_Param->jedi_name[2] = Name_Param->last_name[2]; 
       Name_Param->jedi_name[3] = Name_Param->first_name[0]; 
       Name_Param->jedi_name[4] = Name_Param->first_name[1]; 
       printf("Jedi Name for %s %s is %s\n", Name_Param->first_name, Name_Param->last_name, Name_Param->jedi_name); 
     } 

     return; 
} 

void * allocate(unsigned int size){ 
    heap_usage = heap_usage + size; 
    printf("The current heap size after heap allocation is %d\n", heap_usage); 
    void *heapMem = malloc(size); 
    if(heapMem == NULL) 
     printf("Pointer is NULL\n"); 
    else 
     printf("Pointer is not NULL\n"); 

    return heapMem; 
} 

void * deallocate(void *heapMem, int size){ 
    heap_usage = heap_usage - size; 
    printf("The current heap size after heap deallocation is %d\n", heap_usage); 
    free(heapMem); 
    heapMem = NULL; 
    return NULL; 
} 
+0

내가 할당하고 포인터에 할당 해제 메모리 기능을 사용하고 힙 메모리를 추적 할 수있는, 즉'그래서 난 당신이 name''에 대한 모든 공간을 할당하지 않을 –

+1

이러한 기능을 가지고있는 이유 이름 ->'정의되지 않은 동작입니다 – yano

+0

좀 자세히 설명해 주시겠습니까? 이 작업을 수행해야합니까? 이름 == allocate (10); 위의 작업을 수행하는 중 오류가 발생하지 않습니다. –

답변

2

당신은 정의되지 않은 동작을 호출하고을 : 그것은 헤더와 C의 파일로 나누어 져 있습니다 그것을위한 공간을 할당하지 않는다. name에 아무데도 가리키는 포인터가 있습니다 (실제로 정적이기 때문에 0으로 초기화됩니다). main에서는 name = malloc(sizeof *name);처럼 뭔가를해야하거나, 그래서 그냥 거기 선언, namemain에 사용되는, 두 번째 모습에 struct Names name;

에 선언을 변경할 수 있습니다. 더 넓은 범위에서 선언 할 필요가 없습니다.

int main(void) 
{ 
    // no point in dynamically allocating memory in this case. You don't need 
    // much and you know exactly how much you need (just 1 struct) 
    struct Names name; 
    // but if you want to dynamically allocate it.. 
    // struct Names* name = malloc(sizeof *name); 
    .... 
    // change all your "name->" to "name." if you did not malloc 
    // if you did not malloc, you must pass the address of name 
    // to jediName 
    // jediName(&name); 

    // .. do you work 

    // if you used malloc above, don't forget to free your memory 
    // free(name); 

    return 0; 
} 

또한 Why is “while (!feof (file))” always wrong?

+0

allocall()에서 간접적으로 malloc을 사용했으며 deallocate()에서 NULL에 대한 포인터를 해제하고 설정했습니다. 주 이름을 선언하려고 시도했습니다. –

+0

@SagarRikame ' 'struct Name'의 fields/members에 사용했습니다. 구조체 자체에서는 사용하지 않았습니다! 'name' 역시 메모리가 필요합니다. 'name'은'first_name','last_name','jedi_name'과 같은 포인터입니다. 포인터는 이미 존재하는 메모리를 가리켜 야하거나 역 참조하기 전에 자신의 메모리를 할당해야합니다. – yano

+0

name == allocate (sizeof (* name)); deallocate (name-> first_name, sizeof (name-> first_name)); 할당 및 할당 해제 코드의 시작과 끝에이 두 줄을 추가 했는데도 오류가 계속 발생합니다. –

0

덕분에 도움을 많이 참조하십시오. 코드의 주된 문제는 이름에 대한 메모리 할당 누락, '=='및 코드 디버깅 중 작성된 몇 가지 추가 코드입니다.

다음은 최종 c 파일입니다.

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

#include "Structures.h" 

int main(){ 

    char buffer1[250]; 
    char buffer2[250]; 

    FILE * fp; 

     printf("Enter the first & last name : \n"); 
     scanf("%s %s", buffer1, buffer2); 

    fp = fopen("names.txt", "a"); 
    fprintf(fp, "\n%s %s", buffer1, buffer2); 
    fclose(fp); 


    fp = fopen("names.txt","r"); 

     name = allocate(10); 
     name->first_name = allocate(10); 
     name->last_name = allocate(10); 
     name->jedi_name = allocate(10); 

    while(!feof(fp)){ 
     fscanf(fp, "%s %s", name->first_name, name->last_name); 
     jediName(name); 
    } 

    deallocate(name->first_name, 10); 
     deallocate(name->last_name, 10); 
     deallocate(name->jedi_name, 10); 
     deallocate(name, 10); 

    fclose(fp); 

    return 0; 
} 

void jediName(struct Names *Name_Param){ 
     if(strlen(Name_Param->first_name)<2 || strlen(Name_Param->last_name)<3) 
       printf("Name of %s %s is too short to compute a jedi name\n", Name_Param->first_name, Name_Param->last_name); 
     else{ 
       Name_Param->jedi_name[0] = Name_Param->last_name[0]; 
       Name_Param->jedi_name[1] = Name_Param->last_name[1]; 
       Name_Param->jedi_name[2] = Name_Param->last_name[2]; 
       Name_Param->jedi_name[3] = Name_Param->first_name[0]; 
       Name_Param->jedi_name[4] = Name_Param->first_name[1]; 
       printf("Jedi Name for %s %s is %s\n", Name_Param->first_name, Name_Param->last_name, Name_Param->jedi_name); 
     } 

     return; 
} 

void * allocate(unsigned int size){ 
    heap_usage = heap_usage + size; 
    printf("The current heap size after heap allocation is %d\n", heap_usage); 
    void *heapMem = malloc(size); 
    if(heapMem == NULL) 
     printf("Pointer is NULL\n"); 
    else 
     printf("Pointer is not NULL\n"); 

    return heapMem; 
} 

void * deallocate(void *heapMem, int size){ 
    heap_usage = heap_usage - size; 
    printf("The current heap size after heap deallocation is %d\n", heap_usage); 
    free(heapMem); 
    heapMem = NULL; 
    return NULL; 
} 
관련 문제