c

c - ¿Por qué "memset(arr,-1, sizeof(arr)/sizeof(int))" no borra una matriz de enteros a-1?



(6)

¿No es posible usar memset en una matriz de enteros? Intenté la siguiente llamada memset y no obtuve los valores enteros correctos en la matriz int.

int arr[5]; memset (arr, -1, sizeof(arr)/sizeof(int));

Vaules que tengo son:

arr[0] = -1 arr[1] = 255 arr[2] = 0 arr[3] = 0 arr[4] = 0


¿Por qué la división?

memset(arr, -1, sizeof(arr));

Su versión, sizeof(arr)/sizeof(int) , le da el número de elementos en la matriz.


No use memset para inicializar nada más que los tipos de datos de un solo byte.

A primera vista, puede parecer que debería funcionar para inicializar un int a 0 o -1 (y en muchos sistemas funcionará), pero luego no está considerando la posibilidad de que pueda generar una representación de captura, lo que provoca comportamiento indefinido, o el hecho de que la representación entera no es necesariamente el complemento de dos .

La forma correcta de inicializar una matriz de int a -1 , es recorrer la matriz y establecer cada valor explícitamente.


Puede ahorrarse algo de escritura al inicializar la matriz directamente:

int arr[5] = {-1, -1, -1, -1, -1};

Esa línea es más corta que el memset, y también funciona.


Simplemente cambie a memset (arr, -1, sizeof(arr));

Tenga en cuenta que para otros valores que no sean 0 y -1, esto no funcionaría ya que memset establece los valores de bytes para el bloque de memoria que comienza en la variable indicada por *ptr para los siguientes *ptr de bytes.

void * memset ( void * ptr, int value, size_t num );

Y como int se representa en más de un byte, no obtendrá el valor deseado para los enteros en su matriz.

Excepciones:

  • 0 es una excepción ya que, si establece todos los bytes en 0, el valor será cero
  • -1 es otra excepción ya que, como Patrick resaltó -1 es 0xff (= 255) en int8_t y 0xffffffff en int32_t

La razón por la que tienes:

arr[0] = -1 arr[1] = 255 arr[2] = 0 arr[3] = 0 arr[4] = 0

Es porque, en su caso, la longitud de un int es de 4 bytes (representación de 32 bits), la longitud de su matriz en bytes es 20 (= 5 * 4), y solo establece 5 bytes a -1 (= 255) en lugar de 20


gcc proporciona un buen atajo de inicialización de matriz

int arr[32] = {[0 ... 10] = 3, [11 ... 31] = 4}

cuidado con el espacio antes y después ...


void * memset ( void * ptr, int value, size_t num );

Esta función funciona bien en la mayoría de los sistemas cuando se aplica para establecer una matriz de caracteres. Establece el primer número BYTES del bloque de memoria apuntado por ptr al valor especificado (interpretado como un carácter sin signo). Referencia de memset-C ++ Funciona un byte cada vez. Por lo tanto, funciona bien si asigna los segundos argumentos con un valor int no más de 0xff.

En cuanto a su versión, el tercer argumento es el número de elementos de matriz, por lo que obtuvo su salida. En realidad, la verdad es que se supone que debe asignar a los terceros argumentos el NÚMERO DE BONOS que desee. Así que la versión correcta debería ser así:

memset (arr, -1, sizeof(arr));