0

我刚从 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;
}
4

3 回答 3

4
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 中的学生重新排序。所以你应该在完成后释放内存。但是对于学生和 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);
}
于 2012-10-05T02:05:49.810 回答
1

您的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; 
} 
于 2012-10-05T02:08:31.530 回答
0

这个说法

students = &students[x];

修改传入的参数。你已经失去了“学生”所指的东西,这是struct student [].

删除此语句并尝试再次运行您的程序。

还有其他错误,但这应该会让你摆脱困境。

指针很难。

于 2012-10-05T02:05:06.807 回答