Matriz dinámica en C - ¿Mi comprensión de malloc y realloc es correcta?
Estoy aprendiendo a crear arrays dinámicos 1D en C. El siguiente código intenta hacer lo siguiente:
- Usando
malloc
, cree un array dinámico de length10
, que contenga valores de tipodouble
. - Establece cada entrada de la matriz en
j/100
paraj = 0, 1,..., 9
. Entonces imprímelo. - Agregue una entrada vacía adicional al final de la matriz usando
realloc
. - Establezca la nueva entrada en
j/100
e imprima cada entrada nuevo.
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 esto bien?
-
Tutoriales Encontré usar
malloc
sin poner el(double*)
delante. Por ejemplo,Int * pointer;
pointer = malloc(2 * sizeof (int));
Esto no 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 suponer que es porque los compiladores que están usando rellenan automáticamente el (int*)
para ellos en mi ejemplo?
3 answers
Estás cerca.
En C (al menos desde la versión de 1989 del estándar), el molde antes de malloc
y realloc
es innecesario, ya que C puede convertir valores de tipo void *
a int *
sin un molde. Esto es no verdadero para C++, así que basado en el error que está obteniendo, suena como si estuviera compilando este código como C++ y no C. Consulte la documentación de VS2010 para determinar cómo compilar código como C.
El siguiente es mi estilo preferido para escribir un malloc
llamada:
double *data = malloc(10 * sizeof *data);
Ya 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 lenguaje desde entonces, que han introducido algunas características nuevas y obsoletas. Así, mientras que algunos compiladores de C soportan características de C99 como declaraciones mixtas y código, matrices de longitud variable, etc., VS2010 no lo hará.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-10-01 15:18:18
1) ¿Estoy codificando bien esto?
En su mayoría. Pero data = (double*)realloc(data,11*sizeof(double));
pierde la referencia a la memoria asignada si realloc
falla, debe usar un puntero temporal para mantener el valor devuelto de realloc
y verificar si es NULL
(y también debe verificar el valor devuelto de malloc
).
2) Tutoriales He encontrado uso malloc sin poner el (doble*) en frente.
En C, malloc
devuelve un void*
que se puede convertir implícitamente a cualquier otro tipo de puntero, por lo que no cast es necesario (y ampliamente desaconsejado porque casting que puede ocultar errores). Visual Studio aparentemente compila el código como C++ donde se requiere el cast.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-10-01 15:11:18
En C, no debe lanzar el valor devuelto de malloc()
.
Además, es una mala idea codificar el tipo en el argumento malloc()
. Esta es una mejor manera:
double* data = malloc(10 * sizeof *data);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-10-01 15:09:25