C - initialize array of structs

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.


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.