2009-08-25 9 views
10

Tengo una matriz de valores arbitrarios, por lo que la he definido como una matriz de punteros vacíos, por lo que puedo señalar cualquier tipo de información (como int, matrices de caracteres, etc.). Sin embargo, ¿cómo le asigno realmente un int?Si tengo un puntero de vacío, ¿cómo puse un int en él?

Tomemos por ejemplo estas inicializaciones:

void* data[10]; 
int x = 100; 

Mi intuición podría pensar esto, pero esto da un error de compilación:

data[0] = malloc(sizeof(int)); 
*(data[0]) = x; 

También pensé en usar &x, pero me tomaría la dirección de una variable local, que (a mi entender) se borrará después de salir del procedimiento. Entonces, si tengo una variable local x, ¿cómo la obtendría correctamente en un tipo de variable de puntero nulo?

Respuesta

24
*((int*)data[0])=x; 

lo hará.

Es posible que desee considerar el uso de una unión. Algo como esto:

union myvalues 
{ 
    int i; 
    double d; 
    long l; 
}; 

A continuación, podría tener

union myvalues *foo[10]; 
foo[0] = malloc(sizeof(union myvalues)); 
foo[0]->i = x; 

También puede typedef la unión. sizeof(union myvalues) será el máximo de sizeof los miembros. Por lo tanto, si tiene int i; y char c[40] en la unión, sizeof(union myvalues) será 40. Al escribir en i, se sobrescribirán los primeros 4 caracteres en c (suponiendo que sus datos sean 4 bytes).

+0

O simplemente usa una matriz de uniones, y olvida el malloc –

+0

De hecho, buen punto. Iba con el más cercano al original. –

+0

Gracias, pero esto también funcionaría con punteros de matriz de caracteres (char *).¿Y esto no causaría problemas de alineación en algunas plataformas? Y finalmente, si tengo un char [40], parece una pérdida de memoria reservar 40 bytes si solo voy a utilizar 4. :-) – pbean

9
*((int *)data[0]) = x; 

Se realizará una copia de x, por lo que el hecho de que sea una variable local no es importante.

1

de aliasing motivos que su mucho mejor hacer

mempcy(data[0], &x, sizeof(int)); 

Da la casualidad que el compilador optimizará la llamada memcpy como sizeof (int) es un valor constante, sino que no se romperá diversas normas aliasing.

+0

¿qué reglas de aliasing? –

+0

Supongo que Goz está preocupado por el tipo de juego de palabras, pero como no puede eliminar la referencia 'void *', siempre es seguro que AFAIK alias con un puntero 'void *'. Simplemente no lo desreferencia después de enviar a otra cosa que no sea 'int *' o 'char *'. –

2

Aunque se puede utilizar un molde para hacer la tarea, es probable que sea mucho más limpio para escribir el código como:

 
void *data[ 10 ]; 
int x = 100; 
int *p; 

p = malloc(sizeof *p); 
data[ 0 ] = p; 
*p = x; 
+0

Estoy de acuerdo con usted por este simple ejemplo, y ese fue el método que elegí primero. Sin embargo, el problema es que hay muchos tipos de datos diferentes posibles, por lo que tendría que declarar una gran cantidad de variables locales temporales que podrían o no ser utilizadas en una ejecución determinada. – pbean

+0

+1 por usar menos puntuación – sigjuice

1

intente esto:

data[0] = malloc(sizeof(int)); 
*((int*)data[0]) = x; 

o

(int) (*(data[0])) = x; 

no se olvide de

free (data[0]); 

después.

Cuestiones relacionadas