J'ai une affectation où je veux implémenter un tableau croissant dynamiquement, mais je semble avoir quelques problèmes avec realloc(). Mon code fonctionne tant que je ne parviens pas à la partie realloc(), où, pour une raison quelconque, seules certaines valeurs spécifiques sont changées pour quelque chose de différent. Maintenant, je m'attendrais à ce que les lignes soient complètement différentes si j'écrivais/lisais hors des limites, mais je n'arrive pas à le localiser. Le problème semble se situer entre les lignes 30-40. Voici le code:Comportement non intentionnel après realloc() avec le tableau dynamique
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4
5 typedef struct __student {
6 unsigned long ID;
7 char fname[33];
8 char lname[33];
9 float grade;
10 } student;
11
12 void partA(FILE *fp) {
13
14 int i, r;
15 i = r = 0;
16 int N = 1000;
17 student **S;
18
19 S = malloc(sizeof(student *) * N);
20
21 // While EOF has not been reached
22 while(!feof(fp)){
23 // Allocate enough memory to hold each student struct
24 S[i] = malloc(sizeof(student));
25 // Get each line and, using a scanset, get corresponding
26 // data into respective struct fields
27 fscanf(fp, "%d %[^,], %s %f", &S[i]->ID, S[i]->lname, S[i]->fname, &S[i]->grade);
28 i++; // Get next line into a new struct
29
30 // If array size has been reached...
31 if(i == N){
32 N *= 2;
33 // Double it
34 S = realloc(S, sizeof(student) * N);
35 if(S == NULL) {
36 // realloc has failed
37 printf("Memory reallocation failed; Fatal error.");
38 break;
39 }
40 }
41 }
42 r = i-1;
43 // Output data
44 printf("Name\t\t\t\t\t\t\t\t [ID]\t\t:\tGrade\n");
45 printf("___________________________________________________________________________________________________\n");
46 for(i=0; i<r; i++){
47 printf("%-32s %-32s [%lu]\t:\t%.3f\n", S[i]->fname, S[i]->lname, S[i]->ID, S[i]->grade);
48 free(S[i]);
49 }
50 }
Voici le fichier d'entrée J'utilise:
58205720 Broke, Jim 95
29571057 Crowe, John 88
12957206 Moore, Kim 22
59376027 Sarasvaki, Joe 79
49027650 Morrigan, Tracy 68
30773967 Trund, Geoffrey 99
34850470 Perry, Tracey 77
70209658 Oatnel, Skye 89
Le résultat attendu est la suivante (que je faire obtenir aussi longtemps que N est élevé, à savoir. plus que le nombre réel de lignes et ne provoque pas realloc() à invoquer):
Name [ID] : Grade
___________________________________________________________________________________________________
Jim Broke [58205720] : 95.000
John Crowe [29571057] : 88.000
Kim Moore [12957206] : 22.000
Joe Sarasvaki [59376027] : 79.000
Tracy Morrigan [49027650] : 68.000
Geoffrey Trund [30773967] : 99.000
Tracey Perry [34850470] : 77.000
Skye Oatnel [70209658] : 89.000
Cependant, si je mets N = 3, je reçois le texte suivant:
Name [ID] : Grade
___________________________________________________________________________________________________
Jim Broke [58205720] : 95.000
John Crowe [29571057] : 88.000
Kim Moore [12957206] : 22.000
Joe Sarasvaki [59376027] : 79.000
Tracy Morrigan [49027650] : 68.000
Geoffrey Trund [30773967] : 99.000
Tracey Perry [231963084454] : 77.000
Skye Oatnel [231998443642] : 89.000
Je suis tout à fait à une perte de ce qui se passe. J'ai essayé d'examiner la pile et les valeurs locales en utilisant gdb, mais je n'ai pas encore eu beaucoup de chance. Je suis également en conflit quant à la raison pour laquelle la carte d'identité est la seule chose à être corrompue. Serait-il nécessaire de faire une fonction séparée qui retournerait un pointeur vers le nouvel espace que j'obtiendrais par realloc()? Je voulais garder mon code aussi compact que possible, donc j'ai opté pour l'essayer de cette façon d'abord comme la page de manuel semblait sauvegarder mon hypothèse sur la façon dont fonctionne realloc(). Je vous remercie.
Ce n'est pas votre problème principal, mais 'S = realloc (S, sizeof (étudiant) * N);' devrait être 'S = realloc (S, sizeof (étudiant *) * N);'. La mémoire que vous attribuez contient des pointeurs aux étudiants, pas aux étudiants. –
'feof' ne fonctionne pas comme vous le pensez ... –
Pour amplifier ce que dit Carl Norum, vous ne pouvez pas utiliser' feof' pour prédire si une future lecture réussira. Vous devriez vérifier la valeur de retour de 'fscanf'. Cependant, encore une fois, ce n'est probablement pas votre problème principal. –