¿Es necesario multiplicar por sizeof (char) al manipular la memoria?

Cuando uso malloc y hago una manipulación de memoria similar, ¿puedo confiar en que sizeof (char) es siempre 1?

Por ejemplo, necesito asignar memoria para N elementos de tipo char . Es necesario multiplicar por sizeof( char ) :

 char* buffer = malloc( N * sizeof( char ) ); 

o ¿puedo confiar en que sizeof (char) siempre es 1 y simplemente omitir la multiplicación?

 char* buffer = malloc( N ); 

Entiendo completamente que se evalúa sizeof durante la comstackción y luego el comstackdor podría incluso comstackr la multiplicación y, por lo tanto, la penalización de rendimiento será mínima y muy probablemente cero.

Estoy preguntando principalmente sobre la claridad del código y la portabilidad. ¿Es esta multiplicación alguna vez necesaria para el tipo char ?

Si bien no es necesario, considero una buena práctica dejarlo en sizeof (char) porque hace que el código sea más legible y evita el uso de un número mágico. Además, si es necesario cambiar el código más adelante para que, en lugar de un carácter, sea cambiar el tamaño de algo a un puntero para ese objeto, es más fácil cambiar el código que si solo tiene un “1”.

Por definición, sizeof (char) siempre es igual a 1. Un byte es el tamaño del carácter en C, independientemente de la cantidad de bits en un byte que haya (8 en la CPU de escritorio común).

El ejemplo típico donde un byte no es de 8 bits es el PDP-10 y otras architectures antiguas similares a mini computadoras con 9/36 bits bytes. Pero los bytes que no son 2 ^ N se están volviendo extremadamente infrecuentes, creo.

Además, creo que este es un mejor estilo:

 char* buf1; double* buf2; buf1 = malloc(sizeof(*buf1) * N); buf2 = malloc(sizeof(*buf2) * N); 

Porque funciona cualquiera que sea el tipo de puntero.

sizeof(char) siempre es 1, independientemente del tipo de manipulación de memoria que realice.

Sin embargo, sizeof(TCHAR) puede variar dependiendo de las opciones de comstackdor.

Lo considero una especie de anti-patrón . Indica que el progtwigdor no sabía muy bien lo que estaba haciendo, lo que inmediatamente arroja el rest del código bajo una luz dudosa.

Por supuesto, no (citando a Wikipedia) es “ineficaz”, pero lo encuentro “lejos de ser óptimo”. No cuesta nada en tiempo de ejecución, pero llena el código con basura innecesaria, todo lo cual indica que alguien pensó que era necesario.

Además, tenga en cuenta que la expresión no se analiza como una llamada de función: sizeof no es una función. No estás llamando a una función que le pasa el símbolo mágico char . Está aplicando el operador de prefijo unario incorporado sizeof a una expresión, y su expresión es en este caso una conversión al tipo char , que en C se escribe como (char) .

Es perfectamente posible, y muy recomendable siempre que sea posible, usar sizeof en otras expresiones, luego se obtendrá el tamaño del valor de la expresión:

 char a; printf("A char's size is %u\n", (unsigned int) sizeof a); 

Esto imprimirá 1 , siempre, en todas las implementaciones de C conformes.

También estoy muy de acuerdo con David Cournapeau y considero repetir el nombre de tipo en un malloc() -también para ser una especie de antipatrón.

En lugar de

 char *str; str = malloc(N * sizeof (char)); 

que muchos escribirían para asignar un búfer de cadena con capacidad de N caracteres, iría con

 char *str; str = malloc(N * sizeof *str); 

O (solo para cadenas) omita el sizeof tal como se sizeof anteriormente, pero esto, por supuesto, es más general y funciona igual de bien para cualquier tipo de puntero.

No es necesario. Ver aquí (por ejemplo).

sizeof(char) está definido por el estándar C como siempre 1 (byte). Tenga en cuenta que debido a que sizeof devuelve una cantidad de bytes, el número de bits por byte es irrelevante (y en términos prácticos es 8).

Otra cosa a tener en cuenta es que el comstackdor sabe estáticamente que el valor de sizeof (char) es 1 y también sabe que multiplicar un número por un 1 estático implica que la multiplicación no tiene que hacerse; El comstackdor lo optimizará. Las preocupaciones de rendimiento no deben entrar en consideración por estos motivos.

De “Nuevo estándar de C. Un comentario económico y cultural”.

  1. Estadísticas: el 2.0% de sizeof se toma de char y el 1.5% de unsigned char . Página 1033 en la versión 1.2 del libro.
  2. página 1037.

El número de bits en la representación de un tipo de carácter es irrelevante. Por definición, el número de bytes en bytes de un tipo de carácter es uno.

Pautas de encoding Los desarrolladores a veces asocian un byte que siempre contiene ocho bits. En los hosts donde el tipo de carácter es de 16 bits, esto puede llevar a la suposición incorrecta de que la aplicación de sizeof a un tipo de carácter devolverá el valor 2. Estos problemas se discuten en otra parte.

El uso de sizeof (char) hace que su código sea más legible y portátil.

En x86, todos sabemos que un carácter es de 1 byte. Pero escribirlo explícitamente ayuda a aclarar sus intenciones, lo que siempre es bueno.

Además, ¿qué pasa si su código se pone en alguna otra plataforma donde un personaje no es 1 byte. ¿Qué pasaría si un personaje fuera solo de 4 bits?

De acuerdo, no es necesario, pero no ralentiza el tiempo de ejecución y se verá recompensado en el caso excepcional en que necesite transferir su código a una architecture diferente.