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/100paraj = 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/100e 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
mallocsin 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á.