C - initialize array of structs

84,917

Solution 1

This is incorrect:

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

You do not want a **. You want a * and enough space for how ever many students you need

student *students = malloc(numStudents * sizeof *students); // or sizeof (student)
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;
}

If you still want to use the code in your "//add struct" section, you'll need to change the line:

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

to

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

You were getting "initialization from incompatible pointer type" because you were attempting to initialize a pointer to student with an object of type student.

Solution 2

Unrelated to the compiler warnings, but your initial malloc is wrong; you want:

malloc(sizeof(student *)* numStudents)

To allocate room for a total of 'numStudents' pointers to a student. The line:

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

Should be:

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

There's no such thing as 'struct student'. You've declared an unnamed struct and typedef'd it to 'student'. Compare and contrast with:

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

};

Which would create a 'struct student' type but require you (in C) to explicitly refer to struct student rather than merely student elsewhere. This rule is changed for C++, so your compiler may be a bit fuzzy about it.

As for:

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

That should be:

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

As the curly brace syntax is a direct literal, not something somewhere else that you need to point to.

EDIT: on reflection, I think aaa may have taken more of an overview of this than I have. Is it possible that you're inadvertently using an extra level of pointer dereference everywhere? So you'd want:

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;

And:

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

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

Subject the array not being used outside of scope of newStudent. Otherwise copying the pointers to strings is incorrect.

Solution 3

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;
}
Share:
84,917

Related videos on Youtube

Admin
Author by

Admin

Updated on August 01, 2020

Comments

  • Admin
    Admin almost 4 years

    I am having a problem initializing an array of structs. I'm not sure if I am doing it right because I get "initialization from incompatible pointer type" & "assignment from incompatible pointer type". I added in the code where I get these warnings, and when I try to print the data from the struct I just get garbage such as @@###

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

    //initialize array

        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;
    

    //add struct

     //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++;
    
    • Pete Kirkham
      Pete Kirkham over 13 years
      Your code seems to be half way between dynamically creating an array of student structs, and dynamically creating an array of pointers to student structs, and then dynamically creating each student struct which is pointed to. It's not obvious which one you are trying to do, which makes answering this difficult.
  • GnP
    GnP almost 8 years
    Surely you mean student* students = malloc(numStudents * sizeof(student) ), right?
  • pmg
    pmg almost 8 years
    @GnP: I prefer to use the object itself as a argument to the sizeof operator. With struct something *ptr; applying the operator to the (parenthesised) type struct something or to the object *ptr yields the same value. sizeof *ptr == sizeof (struct something).
  • GnP
    GnP almost 8 years
    Thanks @prng. I was confused by the syntax until I realized sizeof is a unary operator and not a function in C.
  • xxks-kkk
    xxks-kkk over 7 years
    why I cannot access my member variable using students[x]->firstName for instance?
  • pmg
    pmg over 7 years
    @zack: because . is used with objects, and -> is used with pointers. After the declaration student *students; every indexing into students yelds an object of type student.