2010-11-13 5 views
15

Ho riscontrato un problema durante l'inizializzazione di una matrice di strutture. Non sono sicuro se lo sto facendo bene perché ottengo "l'inizializzazione dal tipo di puntatore incompatibile" & "assegnazione da tipo di puntatore incompatibile". Ho aggiunto nel codice in cui ottengo questi avvertimenti, e quando provo a stampare i dati dalla struct ottengo solo spazzatura come ad esempio @@ ###C - initialize array of structs

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

}student; 

// inizializza serie

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; 

// aggiunge 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++; 
+1

Il codice sembra essere a metà strada tra la creazione dinamica di una matrice di strutture studente e la creazione dinamica di una serie di puntatori alle strutture degli studenti, e quindi la creazione dinamica di ogni struttura di studenti a cui è indirizzato. Non è ovvio quale stai cercando di fare, il che rende difficile rispondere a questo. –

risposta

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

No, no, no!

Non si desidera un **. Si vuole uno spazio * e sufficiente per come mai gli studenti quanti avete bisogno

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; 
} 
+1

Sicuramente vuoi dire 'studenti * studenti = malloc (numStudents * sizeof (studente))', giusto? – GnP

+1

@GnP: preferisco usare l'oggetto stesso come argomento per l'operatore 'sizeof'. Con 'struct something * ptr;' applicando l'operatore al (parentesi) tipo 'struct something' o all'oggetto' * ptr' si ottiene lo stesso valore. 'sizeof * ptr == sizeof (struct something)'. – pmg

+0

Grazie a @prng. Sono stato confuso dalla sintassi fino a quando ho realizzato che 'sizeof' è un operatore unario e non una funzione in C. – GnP

2
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; 
} 
7

non collegati agli avvertimenti del compilatore, ma la vostra malloc iniziale è sbagliata; desiderato:

malloc(sizeof(student *)* numStudents) 

Per allocare lo spazio per un totale di puntatori "numStudents" a uno studente. La linea:

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

dovrebbe essere:

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

Non esiste una cosa come 'studente struct'. Hai dichiarato una struttura senza nome e l'hai digitata in "studente". Confronta e il contrasto con:

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

}; 

che creerebbe un tipo di 'studente struct', ma si richiede (in C) per fare riferimento in modo esplicito a struct studente piuttosto che semplicemente studente altrove. Questa regola è stata modificata per C++, quindi il compilatore potrebbe risultare un po 'confuso.

quanto riguarda:

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

che dovrebbero essere:

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

Come la sintassi parentesi graffa è una diretta letterale, non qualcosa da qualche altra parte che è necessario per puntare a.

EDIT: sulla riflessione, penso che aaa potrebbe aver preso più di una visione d'insieme di ciò che ho. È possibile che tu stia inavvertitamente usando un livello extra di dereferenziazione puntatore ovunque? Quindi, che ci si vuole:

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; 

E:

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

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

Soggetto matrice non viene utilizzato al di fuori del campo di applicazione della newStudent. In caso contrario, copiare i puntatori su stringhe non è corretto.

-1

Durante l'inizializzazione, shoudn't essere come questo?

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

Tuttavia, perché puntare a un puntatore? Penso solo a un puntatore a struct.