2016-05-17 69 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

'记录**数据,'加起来三颗星。 (记录已经是可怕的typedeffed指针) – 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类型的结构的指针,它是Rec的类型定义。

typedef struct Rec* Record; 

由于data时剥离下来,是Record类型定义,别名的指针的Rec结构。双指针作为参数,这将通过通通过参考被修改的部分,被声明,则确定在输入数据集的行数后,作为指针数组:

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

访问成员数据,对于每个数组中的条目将是:

(*data)[i] dot name_of_member 

规则会改变,有类型的定义是这样的:

typedef struct Rec Record; 

即正常的结构,没有指针的使用。

然后访问该成员的数据本来,如果达到分配,

(*data)[i]->name_of_member 

然而,不要尝试typedef因为这将使悲伤背后隐藏的指针,回来的在未来再次编码,并想知道为什么它失败,隐藏的指针已经咬你!

+0

记录是一个typedef而不是struct。 – 4pie0

0

Record被定义为

typedef struct Rec* Record; 

因此它是指向struct建议malloc返回指向分配的内存(或NULL),但你施放此的指针的指针

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