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で並べ替えます。したがって、完了したらメモリを解放する必要があります。ただし、studentと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が配列インデックスであると仮定します。これが、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 に答える