2010-08-28 2 views
6

Ho un C (non C++) struct che va come questoC array struct

typedef struct mystruct{ 
float a,b; 
int x, y; 
} mystruct; 

Poi in una funzione che raccogliere i dati in questo modo:

mystruct List[MAX]; 
ListNumber = 0; 

for(i = 0; i < MAX; i++) 
{ 
if(conditions_meet) 
{ 
    List[ListNumber].a = masterlist[i].a; 

... ecc

ListNumber++; 
} 
} 

quindi invio l'array a una funzione

DoStuff(static int max, mystruct array[max]){ 
    Stuff 
} 

Questo funziona, ma quando provo a fare in questo modo ....

mystruct setter(int i) 
{ 
mystruct TEMP; 
TEMP.a = masterlist[i].a; 
//......etc 
return TEMP; 
} 


mystruct List[MAX]; 
ListNumber = 0; 

for(i = 0; i < MAX; i++) 
{ 
if(conditions_meet) 
{ 
    List[ListNumber] = setter(i); 
    ListNumber++; 
} 
} 

provoca un sacco di errori funky. Perché sta succedendo? edit: @ tommieb75 Non posso dare molti dettagli, i risultati non sembrano avere un modello. La lista è usata come un modo generalizzato per disegnare cose sullo schermo, e avere la funzione al posto delle impostazioni dirette crea strani problemi nel rendering -e random-, ma non produce affatto errori nel compilatore. gdb mostra alcuni interi come più grandi di un intero, questo è l'unico schema che trovo. La masterlist è una matrice globale di un'altra struttura. I dati devono essere convertiti nella struttura in questo esempio. Nessun avvertimento o errore del compilatore. Posso attivare avvertimenti più sensibili, ma mi viene sempre segnalato un errore generale che posso pensare. Ho intenzione di provare la soluzione selezionata, che dovrebbe essere sufficiente. In ogni caso funzioni simili che restituiscono le strutture sono usate nel mio codice e funzionano tutte perfettamente tranne che in questo caso con una serie di strutture.

+1

Potrebbe postare alcuni degli errori che si stanno ottenendo? – GameFreak

+0

Qualcuno aggiorna la mia memoria: puoi restituire le strutture in base al valore in C? –

+2

perché no? i puntatori dovrebbero essere più veloci, ma potresti tornare di valore. Btw. www.ideone.com e potresti controllare ;-) – nilphilus

risposta

1

Per una semplice impostazione un membro struct hai bisogno di una copia da un intero struct elemento?

mystruct List[MAX]; 
ListNumber = 0; 

for(i = 0; i < MAX; i++) 
{ 
if(conditions_meet) 
{ 
    List[ListNumber].a = masterlist[i].a; 
    ListNumber++; 
} 
} 

Se davvero bisogno di una funzione, utilizzare la destinazione a memoria come parametro di simile:

void setter(mystruct *dest,const mystruct *src) 
{ 
    dest->a = src->a; 
} 
for(i = 0; i < MAX; i++) 
{ 
if(conditions_meet) 
{ 
    setter(&List[ListNumber], &masterlist[i]); 
    ListNumber++; 
} 
} 
+0

Sì, la funzione è di ripulire la funzione un po ', è un enorme pugno nell'occhio difficile da leggere e modificare in modo rapido. Tuttavia questa sembra essere una soluzione interessante, ho intenzione di provarlo. – Balkania

1

ciò che è

mystruct setter(i) 
{ 
mystruct TEMP; 
TEMP.a = masterlist[i].a; 

'i' non ha alcun tipo?

// Se vengono segnalati errori con i membri non inizializzate in struct che potrebbe aiutare http://ideone.com/WRLVG

+1

È implicitamente int. – Potatoswatter

+0

Argomenti @Potatoswatter? Mi ricordo dei valori di ritorno, ma non degli argomenti (comunque hai ragione) – nilphilus

0

Il primo problema è la tua definizione di setter non è una firma di funzione legale. Il parametro i deve essere dato un tipo

mystruct setter(int i) { 
    ... 
} 

Si utilizza anche la variabile masterlist non definita nella funzione. Questo può essere dichiarato legalmente altrove come statico. In caso contrario, sarà necessario accedere alla funzione in qualche modo

+0

La masterlist è globale. Non conosco il nome proprio in C, anche se ... comunque il codice che ho digitato è stato per lo più realizzato al volo, altrimenti sarebbe stato troppo grande. – Balkania

+0

Anche quello non era copia-incolla del codice reale, ho appena fatto un esempio al volo per rimuovere tutto il rumore circostante ... ovviamente la cosa vera ha capito bene, o il mio compilatore si lamenterebbe: P – Balkania

+0

@Blakania: Tu Non otterrete risposte utili, dal momento che il vostro esempio inventato sembra aver omesso il vero problema. – caf

0

Il problema è che all'interno della funzione setter è presente una variabile allocata nello stack TEMP che esce dall'ambito di applicazione una volta che la funzione è tornata ... potrebbe essere migliore di destinare il puntatore my_struct sul mucchio e restituire l'indirizzo di nuovo fuori alla routine chiamante ...

Edit:

mystruct *setter(int i){ 
    mystruct *ptr_myStruct; 
    ptr_myStruct = malloc(sizeof(mystruct)); 
    if (ptr_myStruct != NULL){ 
     ptr_myStruct->a = masterlist[i].a 
     // etc... 
     return &ptr_myStruct; 
    } 
    return NULL; 
} 

mystruct List[MAX]; 
ListNumber = 0; 

for(i = 0; i < MAX; i++) 
{ 
if(conditions_meet) 
{ 
    List[ListNumber] = setter(i); 
    ListNumber++; 
} 
} 

Questo è ciò che è necessario per ottenere i valori di nuovo fuori una volta che la routine si spegne di scopo.Che si chiama ritorno per riferimento

+0

Viene restituito in base al valore. – Potatoswatter

+0

Differenza tra return-by-value e return-by-reference ... che è quello che sto affermando sopra, restituendo l'indirizzo al puntatore allocato sull'heap restituito per riferimento. – t0mm13b

+0

Se ritornasse per riferimento, ci sarebbe un problema, ma fortunatamente, C non ha questa caratteristica. Se il ritorno per valore non ha funzionato, probabilmente non gli avrebbero permesso di compilare. – Potatoswatter