Foro de elhacker.net

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:

Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. int main( void ){
  5. float *V=NULL;
  6. int N=0,i,ch;
  7. char c;
  8.  
  9. do {
  10. V=( float *)realloc((float *)V,(N+1)*sizeof(float));
  11. printf("\n Ingresa un numero real.................: ");
  12. scanf("%f", &V[N]);
  13. while((ch = getchar()) !='\n' && ch!=EOF);
  14. printf("\n Quieres introducir otro valor? (S/N)...: ");
  15. c=getchar();
  16. N++;
  17. }while (c=='s' || c=='S');
  18.  
  19. for(i=0;i<N;i++)
  20. printf("\n El valor %d es igual a..................: %f\n", i, V[i]);
  21.  
  22. free(V);
  23.  
  24. return 0;
  25. }

Código
  1.     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
Código
  1. 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):
Código
  1. 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. -

 
Código
  1.       ......................
  2.        V =  (float *) malloc(N * sizeof(float));
  3. do {
  4. V = (float*) realloc( V, (N+1)*sizeof(float) );
  5.        .........................

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
Código
  1. int *ptr = (int*)malloc(MAX * sizeof(int));
pero como lo encontré en otro Ej. también funciona, ¿no es necesario incluir...(int*)...?

Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. #define MAX 15
  5. #define TABLA 3
  6.  
  7. int main( void ){
  8. size_t i=1;
  9. int *ptr = malloc(MAX * sizeof(int));
  10.  
  11. while( i<=MAX ){
  12. ptr[i] = i*TABLA;
  13. printf( "\n %2lu x %d = %2d", i, TABLA, ptr[i] );
  14. i++;
  15. }
  16.  
  17. free(ptr);
  18.  
  19. return 0;
  20. }
  21.  
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)

Código
  1. #define MAX 150
  2. #define TABLA 5
  3.  
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
Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. #define MAX 150
  5. #define TABLA 5
  6.  
  7. int main( void ){
  8. size_t i=1;
  9. int *ptr = (int*)malloc(MAX * sizeof(int));
  10.  
  11. while( i<=MAX ){
  12. ptr[i] = i*TABLA;
  13. printf( "\n %2lu x %d = %2d", i, TABLA, ptr[i] );
  14. i++;
  15. }
  16.  
  17. free(ptr);
  18.  
  19. return 0;
  20. }


Título: Re: Arreglo con memoria dinámica en lenguaje C.
Publicado por: geeke en 25 Mayo 2016, 23:04 pm
Código
  1. 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.

Código
  1. int *ptr = (int*)malloc(MAX * sizeof(int)+1);
  2.  


Esta parece mas correcta.-
Código
  1. 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
Código
  1. 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.


Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. #define MAX 150
  5. #define TABLA 5
  6.  
  7. int main( void ){
  8. size_t i=0;
  9. int *ptr = (int*)malloc(MAX * sizeof(int));
  10.  
  11. while( i<MAX ){
  12. ptr[i] = (i+1)*TABLA;
  13. printf( "\n %2lu x %d = %2d", i+1, TABLA, ptr[i] );
  14. i++;
  15. }
  16. free(ptr);
  17. return 0;
  18. }

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.