2009-02-16 21 views
5

Necesito tener un static void* array[1024]; en una biblioteca y necesito tenerlo en NULL para cada entrada.C: array estático

Mi pregunta es sobre la mejor manera de establecer toda la matriz en NULL, ¿es memset (array, NULL, sizeof (void*) * 1024) la mejor solución?

Respuesta

24

static punteros se inicializan automáticamente a NULL. Consulte C99: TC3 6.7.8, §10:

Si un objeto que tiene una duración de almacenamiento automática no se inicializa explícitamente, su valor es indeterminado. Si un objeto que tiene una duración de almacenamiento estático no se inicializa explícitamente, entonces:

  • si tiene un tipo de puntero, se inicializa a un puntero nulo;
  • si tiene tipo aritmético, se inicializa a cero (positivo o sin signo);
  • si es un agregado, cada miembro se inicializa (recursivamente) de acuerdo con estas reglas;
  • si es una unión, el primer miembro nombrado se inicializa (recursivamente) según estas reglas.

Además, contrariamente a lo que otros han escrito,

memset(array, 0, sizeof(array)); 

no está garantizado para dar lugar a punteros nulos. En algunos sistemas, un puntero con todos sus bits configurados en 0 podría ser realmente válido. Para los sistemas convencionales, ese no es el caso, pero con los sistemas integrados, uno nunca sabe.

La manera segura de establecer todas las entradas a un puntero nulo es o bien un bucle sobre las entradas de uno mismo y los puso a NULL, o utilizar un static matriz sin inicializar que puede memcpy() sobre la matriz que desee establecer a NULL.

+0

Tengo curiosidad: ¿cuál es un ejemplo de un sistema para el cual el puntero 0x00 es válido? – Crashworks

+0

Nunca he visto uno (incluso los integrados), @Crashworks, pero el estándar dice que son posibles, por lo que es una buena idea permitirlo si existe la posibilidad de que su software se ejecute allí. El pragmatismo me permite ignorar cómodamente esa regla :-) – paxdiablo

+0

@Crashworks: ver http://www.lysator.liu.se/c/c-faq/c-1.html#1-14 – Christoph

0

No, está mal. No estás considerando el tamaño de cada elemento.

memset(array, 0, sizeof(array)); // this works only on static arrays. 

En general, usted debe utilizar:

memset(array_reference, 0, size_of_array * sizeof(array_element_type)); 
+0

bien, pero mi pregunta era sobre el uso de memset, no sus argumentos. – claf

+0

claferri: La primera línea funciona para su caso. La segunda línea es información más general (para tener en cuenta que memset requiere el tamaño de la matriz en bytes, no la cantidad de elementos) –

9
static void* array[1024] = {0}; 

o, como kmkaplan señala en el comentario, simplemente:

static void* array[1024]; 

aunque me quedo con la primera solución sólo para recordar que está configurado en ceros (el compilador no debe generar ningún código para esto a menos que esté muerto cerebralmente).

No es necesario establecer el memset en absoluto ya que las variables de nivel de archivo se inicializan a cero de todos modos.

Si necesita restablecer a NULL en algún momento después del arranque, utilice:

memset(array, 0, sizeof(array)); 

Esto funciona en la mayoría de las plataformas (cada uno que he visto nunca y eso es mucho), ya que la el puntero nulo suele ser cero bits. Sin embargo, la norma no garantiza de este modo, en esas plataformas oscuros, es más seguro que hacer:

for (i = 0; i < sizeof(array)/sizeof(void*); i++) 
    array[i] = NULL; 
+0

¿se trata de una llamada implícita a memset? – claf

+0

Tenga en cuenta que ni siquiera necesita especificar la parte "= {0}". – kmkaplan

+0

Solo funciona para la inicialización. Es posible que necesite usar memset en una función de biblioteca para restablecer los valores en tiempo de ejecución. –

3

memset lo hará en tiempo de ejecución.

static void* array[1024] = {0}; 

sugerido por Pax lo hará en tiempo de compilación y aumentará el tamaño del ejecutable.

Para una biblioteca, creo que memset es más apropiado.

1

Todo lo que necesita es:


static void* array[1024]; 

porque las variables estáticas se inicializan a 0 todos modos, por lo que no necesitan realmente para iniciar este array, se producirá automáticamente.