2010-09-13 16 views
5

Recentemente ho recensito qualche codice C e ha trovato qualcosa di equivalente a quanto segue:Struct con membro di matrice in C

struct foo { 
    int some_innocent_variables; 
    double some_big_array[VERY_LARGE_NUMBER]; 
} 

essendo quasi, ma non del tutto, quasi interamente un novizio in C, ho ragione di pensare che questa struttura è terribilmente inefficiente nell'uso dello spazio a causa del membro dell'array? Cosa succede quando questa struct viene passata come argomento a una funzione? Viene copiato nella sua interezza nello stack, incluso l'array completo?

Sarebbe meglio nella maggior parte dei casi avere un double *some_pointer?

+0

L'inefficienza nell'uso dello spazio dipende dall'utilizzo o meno dello spazio allocato. Se l'intero array viene sempre utilizzato, un puntatore aggiungerà effettivamente alcuni byte di spazio sprecato per memorizzare il puntatore stesso (anche se trascurabile per i grandi array). – altendky

risposta

7

Se passi di valore, sì, farà una copia di tutto. Ma ecco perché esistono dei puntatori.

//Just the address is passed 
void doSomething(struct foo *myFoo) 
{ 

} 
+0

Per rimanere il più vicino possibile al passaggio per valore mentre si ottiene ancora l'efficienza di riferimento pass-through si può usare 'struct foo const * const myFoo'. Questo dirà al compilatore di avvisarti quando provi accidentalmente a modificare il puntatore o il valore puntato. – altendky

0

Sì, in C di solito si passa un puntatore alla struttura per motivi di efficienza.

2

Essendo passato come argomento sarà copiato che è un modo molto inefficiente delle strutture di passaggio, soprattutto quelli grandi. Tuttavia, fondamentalmente, le strutture vengono passate alle funzioni tramite puntatore.

Scelta tra

double some_big_array[VERY_LARGE_NUMBER]; 

e

double *some_pointer 

dipende solo dalla progettazione del programma e di come questo settore/struttura sarà utilizzata. Quest'ultimo consente l'utilizzo di memoria di dimensioni variabili, tuttavia potrebbe essere necessario l'allocazione dinamica.

+0

+1 a causa di downdota immotivato –

0

Ci sono molti motivi per utilizzare gli array nelle strutture. Tra questi c'è il fatto che le strutture vengono passate alle funzioni in base al valore, mentre gli array vengono passati per riferimento. Detto questo, questa struttura è probabilmente passata alle funzioni con i puntatori.

1

Come altri hanno già detto, gli oggetti di quel tipo vengono solitamente passati in giro con i puntatori (sempre sizeof (struct foo) byte, spesso 4 byte).

Si può anche vedere il "struct hack" (passato anche in giro con puntatori):

struct foo { 
    int some_innocent_variables; 
    double some_array[]; /* C99 flexible array member */ 
    /* double some_array[1]; ** the real C89 "struck hack" */ 
} 

Questa "struct hack" Ottiene una matrice di dimensioni dalla chiamata malloc.

/* allocate an object of struct foo type with an array with 42 elements */ 
struct foo *myfoo = malloc(sizeof *myfoo + 42 * sizeof *myfoo->some_array); 
/* some memory may be wasted when using C89 and 
    the "struct hack" and this allocation method */ 
0

MODIFICA: Quella struttura va bene fintanto che la si passa per riferimento (utilizzando un puntatore).

Offtopic: Attenzione alla struttura, come è not strictly standard compliant; ignora il riempimento automatico. Le code di messaggistica IPC Unix la usano (vedi struct msgbuf), però, e quasi certamente funziona con qualsiasi compilatore.

Detto questo, le funzioni che utilizzano quella struttura possono utilizzare puntatori ad essa anziché utilizzare una copia.