¿Coloco el resultado de malloc?
En esta pregunta, alguien sugirió en un comentario que debería no lanzar el resultado de malloc
, es decir
int *sieve = malloc(sizeof(int) * length);
en lugar de:
int *sieve = (int *) malloc(sizeof(int) * length);
¿Por qué sería este el caso?
2305
3
No; usted no arroja el resultado, ya que:
void *
es automáticamente y con seguridad promovido a cualquier otro tipo de puntero en este caso.. Esto puede causar fallos (o, peor aún, *no* causar un fallo hasta mucho más tarde en alguna parte totalmente diferente del código). Considere lo que ocurre si los punteros y los enteros tienen tamaños diferentes; entonces está ocultando una advertencia mediante un casting y podría perder bits de su dirección devuelta. Nota: a partir de C99 las funciones implícitas han desaparecido de C, y este punto ya no es relevante ya que no se asume automáticamente que las funciones no declaradas devuelvan
int`.Como aclaración, nótese que he dicho "no hay que hacer castings", no "no hay que hacer castings". En mi opinión, es un fallo incluir el casting, incluso si lo haces bien. Sencillamente no hay beneficios en hacerlo, sino un montón de riesgos potenciales, e incluir el yeso indica que no conoces los riesgos.
También hay que tener en cuenta, como señalan los comentaristas, que lo anterior habla de C directo, no de C++. Creo firmemente en C y C++ como lenguajes separados.
Para añadir algo más, tu código repite innecesariamente la información de tipo (
int
) lo que puede causar errores. Es mejor desreferenciar el puntero que se utiliza para almacenar el valor de retorno, para "bloquear" los dos juntos:Esto también mueve la "longitud" al frente para una mayor visibilidad, y elimina los paréntesis redundantes con "sizeof"; sólo son necesarios cuando el argumento es un nombre de tipo. Mucha gente parece no saber (o ignorar) esto, lo que hace que su código sea más verboso. ¡Recuerde:
sizeof
no es una función! :)Mientras que mover
length
al frente puede aumentar la visibilidad en algunos casos raros, también hay que prestar atención a que en el caso general, debería ser mejor escribir la expresión como:Ya que mantener el
sizeof
primero, en este caso, asegura que la multiplicación se hace con al menossize_t
matemático.Compara:
malloc(sizeof *sieve * length * width)
frente amalloc(length * width * sizeof *sieve)
el segundo puede desbordar ellength * width
cuandowidth
ylength
son tipos menores quesize_t
.En C, no es necesario convertir el valor de retorno de
malloc
. El puntero a void devuelto pormalloc
se convierte automáticamente al tipo correcto. Sin embargo, si quieres que tu código compile con un compilador de C++, es necesario hacer un casting. Una alternativa preferida entre la comunidad es utilizar lo siguiente:que además te libera de tener que preocuparte de cambiar el lado derecho de la expresión si alguna vez cambias el tipo de
sieve
.Los lanzamientos son malos, como la gente ha señalado. Especialmente los lanzamientos de punteros.
En C se obtiene una conversión implícita de
void*
a cualquier otro puntero (de datos).