Discussion:
(Grandes) dudas sobre el funcionamiento de malloc() y realloc()
(demasiado antiguo para responder)
Piojo
2003-07-17 14:39:19 UTC
Permalink
p=(float *)malloc(ELEM*sizeof(float));
El cast es innecesario y puede esconder un comportamiento indefinido si
no se incluye stdlib.h. Además, en el sizeof, mejor utilizar p, por si
cambia su tipo. Y, sobre todo, comprobar el valor que devuelve malloc;
es decir...
Cierto. Pero los compiladores de C++ EXIGEN este casting. Y los novatos (que
casi todos empezamos con el maldito TurboC) están hartos de ver warnings
por no hacer el casting.
Además, en "La práctica de la programación" (Kernighan y Pike), se
recomienda hacer los castings, ya que permiten usar el mismo código en
entornos C y C++.

Una cosa más: en el código original echo de menos una línea que diga

free (p);

Aunque la memoria dinámica se libere al terminar el programa, es una buena
práctica liberar todos los recursos de forma explícita dentro del programa.
Así nos evitaremos sustos en sistemas operativos de mentirijilla (todos
sabemos a cuál me refiero). ;)
Fernando Arbeiza
2003-07-17 15:21:27 UTC
Permalink
Post by Piojo
El cast es innecesario y puede esconder un comportamiento indefinido si
no se incluye stdlib.h. Además, en el sizeof, mejor utilizar p, por si
cambia su tipo. Y, sobre todo, comprobar el valor que devuelve malloc;
es decir...
Cierto. Pero los compiladores de C++ EXIGEN este casting. Y los novatos (que
casi todos empezamos con el maldito TurboC) están hartos de ver warnings
por no hacer el casting.
De acuerdo, pero, para un novato, creo que vale más ignorar a sabiendas
un warning que no debería ser tal en algo que se llame compilador de C
[1]; que invocar, sin saberlo, un comportamiento indefinido. Además, en
un novato, no creo que sean tantos warning (no estaremos hablando de
100 000 líneas de código, ¿verdad? ;-).

[1] Estamos hablando de C90 en adelante por supuesto. En el C pre-ANSI
(del K&R 1ª edición), el cast era necesario.
Post by Piojo
Además, en "La práctica de la programación" (Kernighan y Pike), se
recomienda hacer los castings, ya que permiten usar el mismo código en
entornos C y C++.
No se me ocurrirá contradecir algo avalado por Kernighan, pero creo que
tales casos son y deben ser raros, específicos y de pequeños trozos de
código. Y sobre todo, implementados por gente experimentada en los dos
lenguajes; no olvidemos que son dos lenguajes distintos, e intentar
mezclarlos puede tener resultados secundarios no deseados.
Post by Piojo
Una cosa más: en el código original echo de menos una línea que diga
free (p);
Aunque la memoria dinámica se libere al terminar el programa, es una buena
práctica liberar todos los recursos de forma explícita dentro del programa.
Mierda, tienes toda la razón. Se me pasó completamente; sumaré diez
latigazos a cobrar en Semana Santa ;-)
Post by Piojo
Así nos evitaremos sustos en sistemas operativos de mentirijilla (todos
sabemos a cuál me refiero). ;)
No creo que me pueda llevar más sustos en esos sistemas :-)

Un saludo.
--
Fernando Arbeiza <URL: mailto:***@ono.com>
Crea tu propio Linux: <URL: http://www.escomposlinux.org/lfs-es>
J. L.
2003-07-17 17:59:58 UTC
Permalink
Post by Piojo
p=(float *)malloc(ELEM*sizeof(float));
El cast es innecesario y puede esconder un comportamiento indefinido si
no se incluye stdlib.h. Además, en el sizeof, mejor utilizar p, por si
cambia su tipo. Y, sobre todo, comprobar el valor que devuelve malloc;
es decir...
Cierto. Pero los compiladores de C++ EXIGEN este casting.
Esto es totalmente irrelevante aqui.
Post by Piojo
Y los novatos (que
casi todos empezamos con el maldito TurboC) están hartos de ver warnings
por no hacer el casting.
Pero actualmente existen compiladores libres y/o gratuitos (DJGPP,
CygWin, MinGW, Borland C++ para DOS y Windows, ademas de GCC para
Linux/UNIX) que cumplen con el estandard C89 (por supuesto, a traves
de switchs del compilador). Creo que no hay razon para seguir usando
TurboC.
Post by Piojo
Además, en "La práctica de la programación" (Kernighan y Pike), se
recomienda hacer los castings, ya que permiten usar el mismo código en
entornos C y C++.
De nuevo, a pesar de la opinion de Kernighan y Pike (a quienes, por
otra parte, respeto), este es un mal consejo. C++ tiene su propio
mecanismo de asignacion/liberacion de memoria.

Para defrender el uso del (infame) cast, mucha gente se refiere a un
parrafo en "El Lenguaje de Programacion C", 2a. ed. de Kernighan y
Ritchie, que fue el estandard de facto. Aun cuando en la portada se ve
la leyenda "Con Base en el ANSI C", la verdad es que el original es un
a~no anterior al estandard de 1989. Sin embargo, entre las erratas del
libro se encuentra la siguiente (en mi mala traduccion):

pagina 157 (en la edicion en espa~nol (§6.5, hacia el final): La
observacion sobre el cast al valor regresado por malloc ("el metodo
apropiado es declarar que malloc regresa un apuntador a void, despues
forzar explicitamente con un cast al apuntador para hacerlo del tipo
deseado") necesita ser reescrito. El ejemplo es correcto y trabaja,
pero el consejo es discutible en el contexto de los estandares
ISO/ANSI 1998-1989. No solo no es necesario (dado que la conversion de
void * a CUALQUIERTIPO * es automatica), sino que es peligroso si
malloc, o una funcion relacionada, no es declarada como funcion que
regresa void *. El cast explicito puede ocultar un error no
intencional. Por otra parte, en los compiladores pre-ANSI y C++, el
cast es necesario.

(Tomado de http://cm.bell-labs.com/cm/cs/cbook/2ediffs.html)

Dado que Turbo C es un compilador previo a la estandarizacion, el
parrafo anterior explica la necesidad del cast.
Post by Piojo
Una cosa más: en el código original echo de menos una línea que diga
free (p);
Aunque la memoria dinámica se libere al terminar el programa, es una buena
práctica liberar todos los recursos de forma explícita dentro del programa.
Así nos evitaremos sustos en sistemas operativos de mentirijilla (todos
sabemos a cuál me refiero). ;)
Relacionado con Micro$oft? :-).

Saludos

José L. Sanchez Garrido

Loading...