clase - Array dinámico en C-¿Es correcto mi entendimiento de malloc y realloc?
malloc vs calloc (3)
1) ¿Estoy codificando este derecho?
Principalmente. Pero data = (double*)realloc(data,11*sizeof(double));
pierde la referencia a la memoria asignada si falla realloc
, debe usar un puntero temporal para mantener el valor de retorno de realloc
y verificar si es NULL
(y también debe verificar el valor de retorno de malloc
).
2) Los tutoriales que encontré usan malloc sin poner el (doble *) al frente.
En C, malloc
devuelve un void*
que se puede convertir implícitamente a cualquier otro tipo de puntero, por lo que no se necesita un lanzamiento (y se desalienta ampliamente porque el envío puede ocultar errores). Aparentemente, Visual Studio compila el código como C ++ donde se requiere la conversión.
Estoy aprendiendo cómo crear matrices dinámicas 1D en C. El código siguiente intenta hacer lo siguiente:
- Utilizando
malloc
, cree una matriz dinámica de longitud10
, que contenga valores de tipodouble
. - Establezca cada entrada de la matriz en
j/100
paraj = 0, 1,..., 9
. Luego imprímelo. - Agregue una entrada vacía adicional al final de la matriz usando
realloc
. - Establezca la nueva entrada en
j/100
e imprima de nuevo cada entrada.
Pruebas:
double* data = (double*)malloc(10*sizeof(double));
for (j=0;j<10;j++)
{
data[j]= ((double)j)/100;
printf("%g, ",data[j]);
}
printf("/n");
data = (double*)realloc(data,11*sizeof(double));
for (j=0;j<11;j++)
{
if (j == 10){ data[j]= ((double)j)/100; }
printf("%g, ",data[j]);
}
free((void*) data);
Preguntas
¿Estoy codificando este derecho?
Los tutoriales que encontré usan
malloc
sin poner el(double*)
al frente. P.ej,int * puntero;
puntero = malloc (2 * sizeof (int));
Esto no se compila para mí en Visual Studio 2010, Windows 7. El mensaje de error es
el valor de tipo void no se puede asignar a la entidad de tipo
int
.
¿Por qué funciona para esos tutoriales y no para mí? ¿Tengo razón al adivinar que es porque los compiladores que están usando automáticamente llenan el (int*)
para ellos en mi ejemplo?
En C, no debe emitir el valor de retorno de malloc()
.
Además, es una mala idea codificar el tipo en el argumento malloc()
. Esta es una manera mejor:
double* data = malloc(10 * sizeof *data);
Usted está cerca.
En C (al menos desde la versión de 1989 del estándar), el lanzamiento antes de malloc
y realloc
es innecesario, ya que C puede convertir valores de tipo void *
a int *
sin un lanzamiento. Esto no es cierto para C ++, por lo que, según el error que está recibiendo, parece que está compilando este código como C ++ y no C. Consulte la documentación de VS2010 para determinar cómo compilar el código como C.
El siguiente es mi estilo preferido para escribir una llamada malloc
:
double *data = malloc(10 * sizeof *data);
Dado que el tipo de la expresión *data
es double
, sizeof *data
es equivalente a sizeof (double)
. Esto también significa que no tiene que ajustar sus llamadas malloc
si el tipo de data
cambia.
En cuanto a la llamada realloc
, es más seguro asignar el resultado a un valor de puntero temporal. realloc
devolverá NULL si no puede extender el búfer, por lo que es más seguro escribir
double *tmp;
...
tmp = realloc(data, 11 * sizeof *data);
if (!tmp)
{
// could not resize data; handle as appropriate
}
else
{
data = tmp;
// process extended buffer
}
Tenga en cuenta que el soporte de Microsoft para C termina con la versión de 1989 del lenguaje; ha habido dos revisiones del estándar de idioma desde entonces, que han introducido algunas características nuevas y antiguas que han quedado en desuso. Entonces, mientras que algunos compiladores de C admiten características de C99 como declaraciones y código mixtos, matrices de longitud variable, etc., VS2010 no lo hará.