-1

私は初めてCの構造体を扱っていますが、それをよく理解していないと思うことを認めたくありません。学生のデータベース全体を作成するために、学生の構造を指すポインターの配列を構築しようとしています。問題は、複数の学生を作成すると、最初の学生の名前とコースが2番目の学生によって上書きされることです。また、名前だけの出力は本当に奇妙です。「サラ」という名前を付けると、「サラ?LG ?? fa?e」に戻りますが、コースはうまくいきます。メモリ割り当てに何か問題があるように感じますか?私たちもそれについて傾倒したばかりで、私もそれを100%理解していません。

これが私が今取り組んでいるコードの一部です:

typedef struct student Student;

struct student 
{
    char *name;
    int age;
    char *course1;
    char *course2;
};

Student *Data[30];
int count = 0;

void new()
{
    int age;
    char name [300];
    char course1 [300];
    char course2 [300];
    char together[300];
    char remarks[300];

    printf("name: ");
    scanf("%s", name);

    printf("age: ");
    scanf("%d", &age);

    printf("course-1: ");
    scanf("%s", course1);

    printf("course-2: ");   
    scanf("%s", course2);

    Data[count] = malloc(sizeof(Student));
    Data[count]->name = name;
    Data[count]->age = age;
    Data[count]->course1 = course1;
    Data[count]->course2 = course2;
    count++;

}

void display()
{

    int i;
    for(i=0; i<count; i++)
    {
        printf("name:\t%s\n", Data[i]->name);
        printf("age:\t%d\n", Data[i]->age);
        printf("course1:\t%s\n", Data[i]->course1);
        printf("course2:\t%s\n", Data[i]->course2);
    }


}

皆さんの助けに感謝します:)

4

3 に答える 3

1

ああ、あなたは個々のどこにもメモリを割り当てていませんStudent。フィールドのサイズがわかっている場合は、ストレージを構造体の一部として宣言できます。

struct student 
{
   char name[300];
   int age;
   char course1[300];
   char course2[300];
};

そして、次のように入力します。

Data[count] = malloc(sizeof(Student));
strncpy(Data[count]->name, name, sizeof(Data[count]->name));
Data[count]->age = age;
strncpy(Data[count]->course1, course1, sizeof(Data[count]->course1));
strncpy(Data[count]->course2, course2, sizeof(Data[count]->course2));

動的メモリ割り当てを使用する場合、構造体はそのままになりますが、割り当ては変更されます。

Data[count] = malloc(sizeof(Student));
Data[count]->name = strdup(name);
Data[count]->age = age;
Data[count]->course1 = strdup(course1);
Data[count]->course2 = strdup(course2);

....

割り当てを解除するときは、フィールドを忘れないでください。

free(Data[count]->name);
free(Data[count]->course1);
free(Data[count]->course2);
free(Data[count]);
于 2013-03-14T18:48:38.040 に答える
0

それは... 構造体でポインターを処理する通常の方法ではありません。構造体のポインターを、静的に割り当てられたローカル配列に設定しています。やりたいことはmalloc()、配列の構造体メンバーごとのメモリです。例:

void new()
{

    printf("name: ");
    Data[count]->name = malloc(300);
    scanf("%299s", Data[count]->name);

しかし、コードが完成したら、構造体自体だけでなく、すべての構造体の要素のメモリを解放する必要があります。


少し手の込んだものになりたい場合、 or修飾子 (標準によって異なりgccます) を使用してコンパイルするだけで、malloc をスキップできます。%a%m

    printf("name: ");
    scanf("%m", Data[count]->name);

しかしもちろん、自分で解放する必要があります。

于 2013-03-14T18:50:11.817 に答える
0

参照 (ポインター) をデータにコピーしているだけなので、古いデータが失われます。コピーを作成する必要があります

Data[count]->name = (char*)malloc(...);
strcpy(Data[count]->name,name);

等々

于 2013-03-14T18:43:52.543 に答える