sortinger les structures en C avec des pointeurs

Je viens juste de commencer en C et j’ai très peu d’indices sur ce qui se passe dans les coulisses. J’apprends cela instantanément pour un cours sur les structures de données, ce qui rend les choses un peu plus difficiles.

Mise à jour: J’ai supprimé le programme et commence par la mémoire et continue. J’ai les fonctions allocate et deallocate dedans et je reçois une erreur malloc: Q1 (9882) malloc: * erreur pour l’object 0x7fff59daec08: le pointeur libéré n’a pas été alloué * définir un point d’arrêt dans malloc_error_break pour déboguer

Update2 voici mon code révisé, il manque encore quelque chose, quelques déclarations printf ne s’affichent pas:

#include  #include #include #include static int size = 10; struct student{ int id; int score; }; struct student* allocate(){ /*Allocate memory for ten students*/ struct student *s = malloc(size*(sizeof(struct student))); assert(s != 0); /*return the pointer*/ return s; } void generate(struct student* students){ /*Generate random ID and scores for ten students, ID being between 1 and 10, scores between 0 and 100*/ srand((unsigned int)time(NULL)); int id[size]; int y; for (int i = 0; i < size; i++){ y = rand() % size + 1; while(dupe(id, i, y)){ y = rand() % size + 1; } id[i] = y; } for (int j = 0; j id = id[j]; (students + j)->score = rand() % 101; printf("ID: %d\tScore: %d\n", (students + j)->id, (students + j)->score); } } int dupe(int id[], int size1, int i){ for (int x = 0; x < size1; x++){ if(id[x] == i) return 1; } return 0; } void output(struct student* students){ /*Output information about the ten students in the format: ID1 Score1 ID2 score2 ID3 score3 ... ID10 score10*/ sort(&students); for(int x = 0; x id, (students + x)->score); //print stmt not showing } } void sort(struct student* students){ struct student *sd = allocate(); struct student *stud; for(int i = 0; i id] = *stud; } for(int x = 0; x id, (sd + x)->score); //print stmt not showing } students = &sd; deallocate(sd); } void summary(struct student* students){ /*Compute and print the minimum, maximum and average scores of the ten students*/ } void deallocate(struct student* stud){ /*Deallocate memory from stud*/ free(stud); } int main(){ struct student* stud = NULL; char c[] = "------------------------------\n"; /*call allocate*/ stud = allocate(); /*call generate*/ generate(&stud); /*call output*/ printf("%s", c); output(&stud); /*call summary*/ /*call deallocate*/ deallocate(stud); return 0; } 

 students = &students[x]; 

Cela change où les students pointent, de sorte que la prochaine fois dans la boucle, vous serez décalé à partir de là, pas du début. C’est-à-dire que vous recevez les étudiants d’ originalstudents[0] , d’ originalstudents[1] , d’ originalstudents[1+2] , d’ originalstudents[1+2+3] , etc. Vous avez le même problème avec sd .

Au lieu de cela, vous voulez utiliser une variable différente, quelque chose comme

 struct student* st = &students[x]; printf("id = %d\tscore = %d\n", st->id, st->score); etc 

Aussi, à quoi sert SD? Vous semblez allouer de l’espace et copier les étudiants vers SD sans raison apparente. L’espace alloué n’est ni enregistré ni rendu … c’est une fuite de mémoire. Oh, attendez, je vois .. vous réorganisez les étudiants en DD en ordre de leur identifiant. Donc, vous devriez juste libérer la mémoire lorsque vous avez terminé. Mais pour les étudiants et pour sd, vous avez besoin d’un pointeur différent sur le tableau que sur les éléments du tableau. Vous pouvez utiliser de nombreuses conventions de dénomination différentes, mais il est bon d’en utiliser une cohérente. Par exemple:

 void output(struct Student* students){ struct Student *idstudents = allocate(); /* sorted by id */ if (!idstudents) /* handle allocation error */; for (int x = 0; x < 10; x++){ struct Student* student = &students[x]; printf("id = %d\tscore = %d\n", student->id, student->score); struct Student* idstudent = &idstudents[student->id]; *idstudent = *student; /* copy all fields at once */ printf("id = %d\tscore = %d\n", idstudent->id, idstudent->score);/* pointless here, since we just printed the same info via student */ } for (int x = 0; x < 10; x++){ struct Student* idstudent = &idstudents[x]; printf("id = %d\tscore = %d\n", idstudent->id, idstudent->score); } deallocate(idstudents); } 

Votre fonction output() utilise mal les pointeurs, vous piétinez donc les données de votre élève. Essayez quelque chose comme ceci (en supposant que les ID sont des index de tableaux, car c’est ainsi que vous les utilisez):

 struct student* allocate() { /*Allocate memory for ten students*/ struct student *s = malloc(10 * sizeof(struct student)); assert(s != NULL); /*return the pointer*/ return s; } void deallocate(struct student* stud) { /*Deallocate memory from stud*/ free(stud); } int main() { struct student* stud = NULL; /*call allocate*/ stud = allocate(); /*call generate*/ /*call output*/ output(stud); /*call summary*/ /*call deallocate*/ deallocate(stud); return 0; } void output(struct student* students) { /*allocate array for sorting*/ struct student *sd = allocate(); struct student *stud; /*make copy of students in sorted order*/ for (int x = 0; x < 10; ++x) { stud = &students[x]; printf("id = %d\tscore = %d\n", stud->id, stud->score); sd[stud->id] = *stud; } /*output sorted students*/ for (int x = 0; x < 10; ++x) { stud = &sd[x]; printf("id = %d\tscore = %d\n", stud->id, stud->score); } /*deallocate array for sorting*/ deallocate(sd); } 

Comme vous avez codé en dur le nombre d’étudiants, vous pouvez éliminer le besoin d’allouer de manière dynamic un nouveau tableau d’étudiants dans output() et sortinger simplement les pointeurs que vous avez déjà dans le tableau d’origine:

 void output(struct student* students) { /*array for sorting*/ struct student* sd[10]; struct student *stud; /*sort students*/ for (int x = 0; x < 10; ++x) { stud = &students[x]; printf("id = %d\tscore = %d\n", stud->id, stud->score); sd[stud->id] = stud; } /*output sorted students*/ for (int x = 0; x < 10; ++x) { stud = sd[x]; printf("id = %d\tscore = %d\n", stud->id, stud->score); } } 

Mise à jour : maintenant que vous avez montré plus de votre code, vous faites toujours de grosses erreurs avec les pointeurs. Comme vous l’avez montré, votre code ne devrait même pas être compilé. Essayez ceci à la place:

 #include  #include  #include  #include  static const int numStudents = 10; struct student { int id; int score; }; struct student* allocate() { /*Allocate memory for ten students*/ struct student *s = malloc(numStudents * sizeof(struct student)); assert(s != 0); /*return the pointer*/ return s; } void generate(struct student* students) { /*Generate random ID and scores for ten students, ID being between 1 and 10, scores between 0 and 100*/ int id[numStudents]; int y; struct student* stud; for (int i = 0; i < numStudents; i++) { do { y = rand() % size + 1; } while (dupe(id, i, y) != 0); id[i] = y; } for (int j = 0; j < numStudents; j++) { stud = &students[j]; stud->id = id[j]; stud->score = rand() % 101; } } int dupe(int id[], int size, int i) { for (int x = 0; x < size; x++) { if (id[x] == i) return 1; } return 0; } void output(struct student* students) { /*Output information about the students in the format: ID1 Score1 ID2 score2 ID3 score3 ... ID10 score10*/ struct student* stud; for(int x = 0; x < numStudents; x++) { stud = &students[x]; printf("ID: %d\tScore: %d\n", stud->id, stud->score); } } void sort(struct student* students) { struct student *sd = allocate(); struct student *stud; for(int i = 0; i < numStudents; i++) { stud = &students[i]; sd[stud->id - 1] = *stud; } for(int x = 0; x < numStudents; x++) { stud = &sd[x]; students[x] = *stud; } deallocate(sd); } void summary(struct student* students) { /*Compute and print the minimum, maximum and average scores of the ten students*/ } void deallocate(struct student* stud) { /*Deallocate memory from stud*/ free(stud); } int main() { /*seed random number generator*/ srand(time(NULL)); struct student* stud = NULL; const char* c = "------------------------------\n"; /*allocate students and generate info*/ stud = allocate(); generate(stud); output(stud); printf("%s", c); /*sort students*/ sort(students); output(stud); printf("%s", c); /*display summary*/ summary(stud); /*deallocate students*/ deallocate(stud); return 0; } 

Cette déclaration

 students = &students[x]; 

modifie l’argument entrant. Vous avez perdu ce que les «étudiants» ont indiqué, à savoir le début de struct student [] .

Supprimez cette déclaration et essayez de relancer votre programme.

Il y a d’autres erreurs, mais cela devrait vous débloquer.

Les pointeurs sont difficiles.