Test Foro de elhacker.net SMF 2.1

Programación => Programación C/C++ => Mensaje iniciado por: NOB2014 en 24 Mayo 2016, 19:45 PM

Título: Arreglo con memoria dinámica en lenguaje C.
Publicado por: NOB2014 en 24 Mayo 2016, 19:45 PM
Hola, gente. -
Dejo aclarado que son mis inicios con memoria dinámica y puedo estar preguntando cualquier sandez, hay 2 cosas que me tienen intrigado:

#include <stdio.h>
#include <stdlib.h>

int main( void ){
float *V=NULL;
int N=0,i,ch;
char c;

do {
V=( float *)realloc((float *)V,(N+1)*sizeof(float));
printf("\n Ingresa un numero real.................: ");
scanf("%f", &V[N]);
while((ch = getchar()) !='\n' && ch!=EOF);
printf("\n Quieres introducir otro valor? (S/N)...: ");
c=getchar();
N++;
}while (c=='s' || c=='S');

for(i=0;i<N;i++)
printf("\n El valor %d es igual a..................: %f\n", i, V[i]);

free(V);

return 0;
}


     V=( float *)realloc((float *)V,(N+1)*sizeof(float));

En los pocos ejemplos que vi no me parece que estuviera 2 veces en la misma línea el puntero (V) y la otra es ¿no se debería asignar primero con malloc y luego reasignar con calloc? (malloc fuera del bucle do while). -

Es todo, espero me ayuden a aclarar esto. -
Saludos.
Título: Re: Arreglo con memoria dinámica en lenguaje C.
Publicado por: ivancea96 en 24 Mayo 2016, 20:06 PM
Cita de: NOB2014 en 24 Mayo 2016, 19:45 PM
V=( float *)realloc((float *)V,(N+1)*sizeof(float));

En los pocos ejemplos que vi no me parece que estuviera 2 veces en la misma línea el puntero (V) y la otra es ¿no se debería asignar primero con malloc y luego reasignar con calloc? (malloc fuera del bucle do while).
2 veces en la misma línea. ¿Dices que por qué aparece en la misma línea la variable V?
Deja que aclare un poco el código (El (float*) en el primer parámetro es redundante. Estás convirtiendo un float* a float*. En todo caso, tendrías que convertirlo a void*, pero no es necesario):
V = (float*) realloc( V, (N+1)*sizeof(float) );
realloc retorna la nueva dirección de memoria, así que se la asignas al puntero.

No entendí muy bien la segunda pregunta; procedo con:
calloc es igual a malloc, solo que devuelve memoria inicializada toda a 0. No entiendo a qué te refieres con lo de malloc fuera del bucle while. Si realloc recibe un NULL como parámetro, hace lo mismo que malloc.
Título: Re: Arreglo con memoria dinámica en lenguaje C.
Publicado por: NOB2014 en 24 Mayo 2016, 20:46 PM
Hola.
La primer pregunta está clara, en cuanto a la segunda, creí que obligatoriamente se debería hacer algo como esto, pero parece que no es necesario. -

       ......................
        V =  (float *) malloc(N * sizeof(float));
do {
V = (float*) realloc( V, (N+1)*sizeof(float) );
        .........................


Saludos y gracias.
Título: Re: Arreglo con memoria dinámica en lenguaje C.
Publicado por: geeke en 24 Mayo 2016, 21:05 PM
Como ya mencionaron si pasas un puntero NULL y un tamaño distinto a cero a realloc se comporta como malloc es decir reserva memoria. El cast antes de malloc y realloc es innecesario el puntero void* es convertido automáticamente al tipo adecuado.
Título: Re: Arreglo con memoria dinámica en lenguaje C.
Publicado por: NOB2014 en 24 Mayo 2016, 23:40 PM
Hola, geeke, gracias por ocuparte.
Yo debería releer los mensajes, lo que decís de si pasas un puntero NULL y un tamaño distinto a cero a realloc se comporta como malloc (ya lo había dicho ivancea96) ahora que lo repetís me aclaro todo. - 

Saludos.   
Título: Re: Arreglo con memoria dinámica en lenguaje C.
Publicado por: NOB2014 en 25 Mayo 2016, 19:55 PM
Hola.
Estoy todavía un poco perdido y espero que no sea lo mismo que pregunte al principio. -
En la mayoría de los casos encuentro esta declaración para malloc
int *ptr = (int*)malloc(MAX * sizeof(int));
pero como lo encontré en otro Ej. también funciona, ¿no es necesario incluir...(int*)...?

#include <stdio.h>
#include <stdlib.h>

#define MAX 15
#define TABLA 3

int main( void ){
size_t i=1;
int *ptr = malloc(MAX * sizeof(int));

while( i<=MAX ){
ptr[i] = i*TABLA;
printf( "\n %2lu x %d = %2d", i, TABLA, ptr[i] );
i++;
}

free(ptr);

return 0;
}

Saludos.
Título: Re: Arreglo con memoria dinámica en lenguaje C.
Publicado por: ivancea96 en 25 Mayo 2016, 20:27 PM
En C, no es necesario. En C++, sí. Por esa razón, mi recomendación es ponerlo siempre. Pero esto ya es una opinión.
Título: Re: Arreglo con memoria dinámica en lenguaje C.
Publicado por: NOB2014 en 25 Mayo 2016, 22:12 PM
Gracias ivancea...
Con la práctica me surgió un error inesperado, por lo menos para mí, tengo claro que lo podría hacer con una sola variable y volcar el resultado en la misma en cada iteración, pero el caso es que estoy aprendiendo memoria dinámica y me encuentro con este inconveniente. -

(http://i68.tinypic.com/b3kdw5.jpg)

#define MAX 150
#define TABLA 5

Uds. me dirán.
Saludos.
Título: Re: Arreglo con memoria dinámica en lenguaje C.
Publicado por: geeke en 25 Mayo 2016, 22:48 PM
Donde esta el código que produce ese error?
Título: Re: Arreglo con memoria dinámica en lenguaje C.
Publicado por: AlbertoBSD en 25 Mayo 2016, 22:59 PM
Estas haciendo un Free de un valor no inicializado o previamente  liberado.

Necesitamos el codigo.

Saludos.
Título: Re: Arreglo con memoria dinámica en lenguaje C.
Publicado por: NOB2014 en 25 Mayo 2016, 22:59 PM
#include <stdio.h>
#include <stdlib.h>

#define MAX 150
#define TABLA 5

int main( void ){
size_t i=1;
int *ptr = (int*)malloc(MAX * sizeof(int));

while( i<=MAX ){
ptr[i] = i*TABLA;
printf( "\n %2lu x %d = %2d", i, TABLA, ptr[i] );
i++;
}

free(ptr);

return 0;
}
Título: Re: Arreglo con memoria dinámica en lenguaje C.
Publicado por: geeke en 25 Mayo 2016, 23:04 PM
while( i <= MAX )

Estas accediendo fuera de los límites del array con <= cambialo por < o reservar size + 1
Título: Re: Arreglo con memoria dinámica en lenguaje C.
Publicado por: NOB2014 en 25 Mayo 2016, 23:19 PM
¿Es esta la manera correcta?, ya no me da error, estas en lo cierto.

int *ptr = (int*)malloc(MAX * sizeof(int)+1);


Esta parece mas correcta.-
int *ptr = (int*)malloc((MAX+1) * sizeof(int));


Saludos.
Título: Re: Arreglo con memoria dinámica en lenguaje C.
Publicado por: AlbertoBSD en 26 Mayo 2016, 02:51 AM
Muy bien por lo visto estas haciendo una "Tabla" de multiplicar.

Se puede abordar como lo solucionaste. Sin embargo en tu ejemplo queda sin utilizar el elemento 0 de tu arreglo.

Por ejemplo (Un remoto pero posible caso) si vas a guardar en archivo el arreglo

Usando
fwrite(ptr,sizeof(int),MAX,archivo);

Guardarias un ITEM basura (el primero) y omitirias el ultimo
Enonces mejor empezar en el elemento 0 y usar menor que en la comparacion en el while y adicional agregar + 1 en la multiplicación.


#include <stdio.h>
#include <stdlib.h>

#define MAX 150
#define TABLA 5

int main( void ){
size_t i=0;
int *ptr = (int*)malloc(MAX * sizeof(int));

while( i<MAX ){
ptr[i] = (i+1)*TABLA;
printf( "\n %2lu x %d = %2d", i+1, TABLA, ptr[i] );
i++;
}
free(ptr);
return 0;
}


Saludos.
Título: Re: Arreglo con memoria dinámica en lenguaje C.
Publicado por: NOB2014 en 26 Mayo 2016, 03:11 AM
Hola, Alberto. -
Gracias por tu tiempo, realmente te agradezco porque creí que nadie ya me iba a decir si era correcto o no mi solución (muchos en España estarán durmiendo 3:14 de la madrugada), funciona a la perfección y me ayudaste a entender un poco más los arreglos. -

Un abrazo.