[英]sorting structs in C with pointers
我只是從C語言開始,對於幕后發生的事情幾乎一無所知。 我正在為數據結構類動態學習它,這使事情變得更加困難。
更新:我將程序剝離下來,從內存開始,然后繼續。 我在其中有分配和取消分配功能,並且遇到了malloc錯誤:Q1(9882)malloc: *對象0x7fff59daec08的錯誤:未分配釋放的指針*在malloc_error_break中設置斷點以進行調試
Update2這是我的修改后的代碼,仍然缺少一些內容,我的一些printf語句未顯示:
#include <stdio.h>
#include<stdlib.h>
#include<math.h>
#include<assert.h>
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 < size; j++){
(students + 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 < size; x++){
printf("ID: %d\tScore: %d\n", (students + 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 < size; i++){
stud = &students[i];
sd[stud->id] = *stud;
}
for(int x = 0; x < size; x++){
printf("ID: %d\tScore: %d\n", (sd + 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];
這會改變students
指向的位置,因此下一次通過循環時,您將從那里偏移,而不是從頭開始。 也就是說,你要originalstudents[0]
originalstudents[1]
originalstudents[1+2]
originalstudents[1+2+3]
等你有同樣的問題sd
。
相反,您想使用其他變量,例如
struct student* st = &students[x];
printf("id = %d\tscore = %d\n", st->id, st->score);
etc
另外,SD是做什么用的? 您似乎沒有明顯的理由分配一些空間並將學生復制到sd。 分配的空間沒有保存或返回……這是內存泄漏。 哦,等等,我知道..您按學生ID的順序對他們重新排序。 因此,您只需要在完成后釋放內存即可。 但是對於學生和sd,您需要一個指向數組的指針,而不是指向數組元素的指針。 您可以使用許多不同的命名約定,但是最好使用一致的命名約定。 例如:
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);
}
您的output()
函數濫用了指針,因此您在踐踏所有學生數據。 嘗試這樣的事情(假設ID是數組索引,因為那是您使用它們的方式):
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);
}
由於已經對學生數量進行了硬編碼,因此可以消除在output()
動態分配新學生數組的需要,而只需對原始數組中已經擁有的指針進行排序:
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);
}
}
更新 :現在,您已經顯示了更多代碼,仍然在使用指針時犯了一些大錯誤。 如所示,您的代碼甚至不應編譯。 嘗試以下方法:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <assert.h>
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;
}
這個說法
students = &students[x];
修改傳入的參數。 您已經失去了“學生”所指的內容,這是struct student []
的開始。
刪除該語句,然后嘗試再次運行程序。
還有其他錯誤,但這會讓您感到困惑。
指針很難。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.