2017-11-10 36 views
1

私は姓と名の組み合わせであるjedi名を計算するコードを書いています。私はコード全体を書いて、whileループでセグメンテーションフォルトを取得しています。構造体ポインタにテキストファイルを読み込む際のSegfault

以下はコードです。これは、ヘッダとCファイルに分割されています。

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

あなたは間接参照nameしようとすると、未定義の動作を起動しているので、あなたの」そのためにスペースを割り当てないでください。 nameにポインタがあり、どこも指していません(静的なので、実際には0に初期化されていると思います)。 mainでは、name = malloc(sizeof *name);ような何かをしなければならないか、そうちょうどそこにそれを宣言し、nameのみmainに使用され、第二の外観上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

私はallocate() にmallocを間接的に使用しており、deallocate()でNULLにポインタを解放して設定しました メインで名前を宣言しようとしました –

+0

@SagarRikame you ' 'struct Name'のfields/membersに使っています。構造体自体には使用していません! 'name'もメモリが必要です。 'name'は' first_name'、 'last_name'、' jedi_name'のようなポインタです。ポインタは、既存のメモリを指し示す必要があります。または、参照を解除する前に、ポインタを割り当てる必要があります。 – yano

+0

名前== allocate(sizeof(* name)); deallocate(name-> first_name、sizeof(name-> first_name)); 割り当てと割り振りの開始と終了時にこれらの2行を追加しても、エラーは引き続き発生します。 –

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; 
} 
関連する問題