2016-05-17 7 views
0

私はこのサイトでこの問題について十分に見てきましたが、解決策を見つけられませんでした。 私は構造体の配列を持っており、ファイルからいくつかのレコードを読み込んで構造体に格納したいと考えています。問題は、メモリの割り当てです。 これは私が使用して構造体です:C、構造体の配列内の文字列のためのメモリを割り当てる

struct Rec{ 
    int mat; 
    char *nome; 
    char *cognome; 
}; 
typedef struct Rec* Record; 

これはreadFromFile機能である:

void readFromFile(char* fileName, Record** data, int* pn) 
{ 
    char line[LINE_LENGTH]; 
    int n, i; 
    char* token; 
    printf("\n\nReading file %s\n", fileName); 
    FILE* fin = fopen(fileName, "r"); 
    if (fin == NULL) 
    { printf("Error readinf file\n");getch(); 
     goto end; 
    } 
    n = 0;   // first read to know the number of lines 
    while (fgets(line, LINE_LENGTH, fin) != NULL) n++; 
    n = (n < MAX_LENGTH ? n : MAX_LENGTH); 
    printf("N: %d\n", n); 
    *pn = n; 

    //Then I allocate the memory for the n lines I previously read 
    *data = (Record*)malloc(n * sizeof(Record)); 
    if(*data == NULL){ 
    printf("Problem allocating memory\n"); 
    exit(0); 
    } 
    i = 0; 
    for(i = 0; i < n; i++){ 
     (*data)[i].nome = malloc(sizeof(char) * MAX_LENGTH + 1); 
     if((*data)[i]->nome == NULL){ 
      printf("Problem allocating memory\n"); 
      exit(1); 
     } 
     //Here comes the problem, the allocation of the second string fails and the program exit 
     (*data)[i]->cognome = malloc((sizeof(char) * MAX_LENGTH + 1)); 
     if((*data)[i]->cognome == NULL){ 
      printf("Problem allocating memory\n"); 
      exit(2); 
     } 
    } 
    rewind(fin);       
    n = 0; 
    while (fgets(line, LINE_LENGTH, fin) != NULL && n < MAX_LENGTH) 
    { 
     token = strtok(line, ";"); 
     strcpy((*data)[n]->nome, token); 
     token = strtok(line, ";"); 
     strcpy((*data)[n]->cognome, token); 
     token = strtok(line, ";"); 
     (*data)[n]->mat = atoi(token); 
     n++; 

    } 
    fclose(fin);       
    end:return; 
} 

私は多くの方法で構造やコードを変更しようとしましたが、私は、解決策を見つけていませんおそらくポインタの問題だと思うが、私はそれを理解することはできない。 readFromFile関数は教授から提供され、ファイルからintを読み込むために作成されたので、レコードを読み込むためにそれを修正しなければなりませんでした。

+0

'Record ** data、'それは3つの星を追加します。 (レコードはすでに恐ろしい型付きポインタです) – joop

+2

'typedef'の後ろにポインタを隠すべきではありません。 – user694733

+0

も参照してください:https://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc – szczurcio

答えて

0

ポインタへのポインタにキャスト:

(*data)[i].nome = malloc(sizeof(char) * MAX_LENGTH + 1); 

と:

(*data)[i]->cognome = malloc((sizeof(char) * MAX_LENGTH + 1)); 

最初の行は使用されているドット表記では、structのメンバーへのアクセスを意味しますが、 - >は、のメンバーにアクセスすることを意味しますポインタの表記法、すなわち構造体へのポインタを使用する。

(*data)は、タイプ定義のタイプRecordの構造体へのポインタであるため、混乱がそこに表示されています。 dataので

typedef struct Rec* Record; 

ストリッピングとき、Recの構造体へのポインタのエイリアスRecordのタイプ定義は、です。それぞれについて、会員データへのアクセス

*data = (Record*)malloc(n * sizeof(Record)); 

:参照によりパスを介して変更されるパラメータの一部として二重ポインタは、ポインタの配列として、入力データセット内の行の数を決定した後、宣言されています配列内のエントリは次のようになります。通常の構造体、ないポインタの使用状況、つまり

typedef struct Rec Record; 

(*data)[i] dot name_of_member 

ルールが変更されているだろう、型定義は次のようになりました。

その後配分が達成された場合には、悲しみを与えるよう、

(*data)[i]->name_of_member 

しかし、が戻ってくる、typedefの後ろに隠すポインタをしようとしない、データがあったであろうメンバーへのアクセスをもう一度将来コードを作成し、なぜ失敗したのか疑問に思うと、隠れたポインタがあなたに噛まれました!

+0

レコードは構造体ではないtypedefです。 – 4pie0

0

Recordしたがって、撮影を構造体へのポインタである

typedef struct Rec* Record; 

として定義されます。 mallocリターンは割り当てられたメモリ(またはNULL)へのポインタがありますが、これは大きな違いがあります

*data = (Record*)malloc(n * sizeof(Record)); 
// = Rec** 
関連する問題