添加到malloc数组的值将成为malloc数组中的所有值

时间:2012-12-07 20:45:54

标签: c struct malloc arrays

我写过这个函数(下面)。它应该逐行读取文件。编辑该行并将某些单词/字符放入各种功能中。然后将函数放入“进入”结构的数组(malloc)中。

问题在于,当我退出循环并尝试打印出数组时,放入数组的最后一个结构名称变量是唯一打印出来的名称变量。例如,如果我尝试打印出数组的前10个结构名称变量,那么最后一个结构名称变量将被打印出10次。然而,整数(数字变量)工作正常。

我使用fgets()读取文件的行,然后从文件末尾的循环中断。可能fgets()可能是问题,但这似乎不太可能......

我不知道问题是什么,但正如我所说,数字变量打印正常,但名称仅打印出最后一个。

但是从文件中获取信息却没有。如果将我的循环打印语句放在while循环中,它仍然无效。

需要注意的一点是,使用strtok,strcpy和strcat将行放入单独的变量中工作正常。我不认为这是造成它的原因。

struct entrant {
  int number;
  char *name;
};


void read_in_entrants(char fileName[]) {
    FILE *fr;
    fr = fopen(fileName, "rt");

    //Init.
    struct entrant * entrant_array = (struct entrant*) malloc(sizeof (struct entrant));
    int j, temp, k = 0;
    int *number;
    char line[80];
    char name[80];
    char surname[80];

    while(1) {
        //Read line in file.
        fgets(line, 80, fr);

        //If at end of file break from loop.
         if (feof(fr)) break;

        //Edit line to be stored in variables.
        number = strtok(line, " ");
        strcpy(name, strtok(NULL, " "));
        strcpy(surname, strtok(NULL, " "));
        strcat(name, " ");
        strcat(name, surname);

        //Add variables to struct array.
        entrant_array[k].number = atoi(number);
        entrant_array[k].name = name;
        printf(" %d %s\n", entrant_array[k].number, entrant_array[k].name);

        //Handle malloc array memory.
        temp = realloc(entrant_array, (k + 2) * sizeof (struct entrant));
        if (temp != NULL) {
            entrant_array = temp;
        } else {
            free(entrant_array);
            printf("Error in memory allocation!");
            return 1;
        }
        //Increase k.
        k++;
    }

    //Print struct values in array.
    for (j = 0; j < 10; j++) {
        printf(" %d %s", entrant_array[j].number, entrant_array[j].name);
    }

   //Shut down.
   free(entrant_array);
   fclose(fr);
}

无论如何,我一直在努力工作几个小时,我无法解决它。我对C的了解非常有限,我很想知道我需要做些什么才能解决这个问题。

感谢您的帮助,非常感谢:)

1 个答案:

答案 0 :(得分:4)

entrant.name是一个指针,您将指定给同一个本地char数组。所以所有指针都指向同一个变量,它只包含你读到的最后一个东西。在它超出范围之前,它将指向随机存储器。

最快的解决方法是替换

entrant_array[k].name = name;

entrant_array[k].name = strdup(name);

但是你需要记住以后释放那个记忆。