con clase array c arrays malloc realloc

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:

  1. Utilizando malloc , cree una matriz dinámica de longitud 10 , que contenga valores de tipo double .
  2. Establezca cada entrada de la matriz en j/100 para j = 0, 1,..., 9 . Luego imprímelo.
  3. Agregue una entrada vacía adicional al final de la matriz usando realloc .
  4. 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

  1. ¿Estoy codificando este derecho?

  2. 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á.