2010-09-13 20 views
5

Recientemente he revisado algo de código C y encontró algo equivalente a lo siguiente:Struct con miembro de la matriz en C

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

ser casi, pero no del todo, casi en su totalidad un novato en C, Estoy en lo cierto al pensar que esta estructura es terriblemente ineficiente en el uso del espacio debido al miembro de la matriz? ¿Qué sucede cuando se pasa esta estructura como argumento a una función? ¿Está copiado en su totalidad en la pila, incluida la matriz completa?

¿Sería mejor en la mayoría de los casos tener un double *some_pointer en su lugar?

+0

La ineficiencia en el uso del espacio depende de si usa el espacio asignado o no. Si toda la matriz se usa siempre, un puntero agregará algunos bytes de espacio perdido para almacenar el puntero (incluso si es insignificante para las matrices grandes). – altendky

Respuesta

7

Si pasa por el valor sí, hará una copia de todo. Pero es por eso que existen punteros.

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

} 
+0

Para estar lo más cerca posible de pasar de valor al tiempo que obtiene la eficiencia de pasar por referencia, puede usar 'struct foo const * const myFoo'. Esto le indicará al compilador que lo advierta cuando accidentalmente intente modificar el puntero o el valor apuntado. – altendky

0

Sí, en C generalmente pasaría un puntero a la estructura debido a razones de eficiencia.

2

Al pasar como un argumento se copiará que es una forma muy ineficiente de pasar estructuras, especialmente las grandes. Sin embargo, básicamente, las estructuras se pasan a las funciones por puntero.

La elección entre

double some_big_array[VERY_LARGE_NUMBER]; 

y

double *some_pointer 

sólo depende del diseño del programa y cómo este campo/estructura será utilizada. El último permite el uso de almacenamiento de tamaño variable, sin embargo, puede necesitar una asignación dinámica.

+0

+1 debido a downvote no motivado –

0

Hay muchas razones para usar matrices en las estructuras. Entre ellos está el hecho de que las estructuras se pasan a las funciones por valor, mientras que las matrices se pasan por referencia. Dicho esto, esta estructura probablemente se pase a funciones con punteros.

1

Como han dicho otros, los objetos de ese tipo generalmente se pasan con punteros (siempre sizeof (struct foo) bytes, a menudo 4 bytes).

También puede ver el "truco estructura" (también pasa alrededor con punteros):

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

Esta "estructura Hack" Obtiene una matriz de tamaño por la llamada 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

EDITAR: Esa estructura está bien siempre que la pase por referencia (usando un puntero).

Offtopic: Tenga cuidado con el hack de estructura, como es not strictly standard compliant; ignora el relleno automático. Sin embargo, las colas de mensajería Unix IPC lo usan (ver struct msgbuf), y es casi seguro que funcione con cualquier compilador.

Dicho esto, las funciones que usan esa estructura pueden usar punteros a ella en lugar de usar una copia.