C - инициализировать массив структур - PullRequest
17 голосов
/ 13 ноября 2010

У меня проблема с инициализацией массива структур. Я не уверен, правильно ли я это делаю, потому что я получаю «инициализацию из несовместимого типа указателя» и «назначение из несовместимого типа указателя». Я добавил в код, где я получаю эти предупреждения, и когда я пытаюсь распечатать данные из структуры, я просто получаю мусор, такой как @@ ###

typedef struct
{
    char* firstName;
    char* lastName;
    int day;
    int month;
    int year;

}student;

// инициализировать массив

    student** students = malloc(sizeof(student));
    int x;
    for(x = 0; x < numStudents; x++)
    {
        //here I get: "assignment from incompatible pointer type" 
        students[x] = (struct student*)malloc(sizeof(student));
    }

    int arrayIndex = 0;

// добавить структуру

 //create student struct
        //here I get: "initialization from incompatible pointer type"
        student* newStudent = {"john", "smith", 1, 12, 1983};

        //add it to the array
        students[arrayIndex] = newStudent;
        arrayIndex++;

Ответы [ 4 ]

28 голосов
/ 13 ноября 2010

Это неверно:

student** students = malloc(sizeof(student));

Вы не хотите **.Вы хотите * и достаточно места для того, сколько студентов вам нужно

student* students = malloc(numStudents * sizeof *students);
for (x = 0; x < numStudents; x++)
{
    students[x].firstName = "John"; /* or malloc and strcpy */
    students[x].lastName = "Smith"; /* or malloc and strcpy */
    students[x].day = 1;
    students[x].month = 12;
    students[x].year = 1983;
}
7 голосов
/ 13 ноября 2010

Не связано с предупреждениями компилятора, но ваш исходный malloc неверен; Вы хотите:

malloc(sizeof(student *)* numStudents)

Чтобы выделить место для общего количества указателей 'numStudents' для студента. Линия:

students[x] = (struct student*)malloc(sizeof(student));

Должно быть:

students[x] = (student*)malloc(sizeof(student));

Нет такой вещи, как "структура студента". Вы объявили безымянную структуру и напечатали ее как 'student'. Сравните и сопоставьте с:

struct student
{
    char* firstName;
    char* lastName;
    int day;
    int month;
    int year;

};

Который мог бы создать тип «struct student», но потребовал бы, чтобы вы (в C) явно ссылались на struct student, а не просто на студент в другом месте. Это правило изменено для C ++, поэтому ваш компилятор может быть немного нечетким по этому поводу.

Что касается:

student* newStudent = {"john", "smith", 1, 12, 1983};

Это должно быть:

student newStudent = {"john", "smith", 1, 12, 1983};

Поскольку синтаксис фигурных скобок является прямым литералом, а не чем-то другим, на что вам нужно указать.

РЕДАКТИРОВАТЬ: поразмыслив, я думаю, ааа, возможно, взял больше обзора этого, чем я. Возможно ли, что вы случайно используете дополнительный уровень разыменования указателя повсюду? Итак, вы хотите:

student* students = malloc(sizeof(student) * numStudents);

/* no need for this stuff: */
/*int x;
for(x = 0; x < numStudents; x++)
{
    //here I get: "assignment from incompatible pointer type" 
    students[x] = (struct student*)malloc(sizeof(student));
}*/

int arrayIndex = 0;

И

student newStudent = {"john", "smith", 1, 12, 1983};

//add it to the array
students[arrayIndex] = newStudent;
arrayIndex++;

Подчеркнуть, что массив не используется вне области newStudent. В противном случае копирование указателей на строки некорректно.

3 голосов
/ 13 ноября 2010
student* students = malloc(sizeof(student)*numStudents);
int x;
for(x = 0; x < numStudents; x++)
{
    student newStudent = {"john", "smith", 1, 12, 1983}; // string copy are wrong still
    students[x] = newStudent;
}
0 голосов
/ 13 ноября 2010

При инициализации не должно быть так?

student** students = (struct student**)malloc(sizeof(student*)*numStudents);

Однако зачем указатель на указатель? Просто с указателем на структуру достаточно я думаю.

...