Foros del Web » Programación para mayores de 30 ;) » C/C++ »

Asignacion dinamica de memoria

Estas en el tema de Asignacion dinamica de memoria en el foro de C/C++ en Foros del Web. Hola, con el código en C que pongo a continuación intento conseguir que se lea un vector del que previamente no se sabe el tamaño, ...
  #1 (permalink)  
Antiguo 24/03/2008, 17:55
 
Fecha de Ingreso: noviembre-2004
Mensajes: 2
Antigüedad: 19 años, 6 meses
Puntos: 0
Pregunta Asignacion dinamica de memoria

Hola,

con el código en C que pongo a continuación intento conseguir que se lea un vector del que previamente no se sabe el tamaño, y una vez leido lo imprima en pantalla. Uso malloc y realloc para ir asignando memoria conforme se van añadiendo elementos al vector. El problema es que si el vector es de uno o dos elementos me los imprime bien, pero si tiene tres o más elementos, curiosamente solo imprime bien el segundo elemento (indice 1) , el primero lo imprime a cero y el resto va dando valores extrños (siempre los mismos), ¿Por qué ocurre esto? Muchas gracias. Saludos.

El código es el siguiente:

#include <stdio.h>

void leer_vector(int *vect, int *n); //Carga un vector de tamaño indeterminado
void imprime_vector(int *vect, int n); //Imprime un vector de tamaño n

int main()
{
int norigen; //Número de elementos del vector origen

int *vectororigen;
vectororigen = NULL;
int tamano = 1*sizeof(int);
vectororigen = (int *) malloc( tamano );

leer_vector(vectororigen, &norigen);
imprime_vector(vectororigen, norigen);

return 0;
}

void leer_vector(int *vect, int *n)
{
int i=0;
char respuesta;
int nuevo_tamano=0;

do
{
fflush(stdin);
printf("\n¿Elemento %d del vector origen?", i+1);
scanf("%d", &vect[i]);
fflush(stdin);
printf("\n¿Otro elemento?(S/N)");
scanf("%c", &respuesta);
if (respuesta=='s' || respuesta=='S')
{
nuevo_tamano = sizeof(int)*(i+2);
vect = (int *) realloc (vect, nuevo_tamano );
i++;
}
*n = i+1;

}while(respuesta=='s' || respuesta=='S');
}


void imprime_vector(int *vect, int n)
{
int i;

for(i=0; i<n; i++)
printf("\t%d", vect[i] );
printf("\n");
}
  #2 (permalink)  
Antiguo 25/03/2008, 08:01
Avatar de _Lucifer_  
Fecha de Ingreso: junio-2006
Mensajes: 1.662
Antigüedad: 17 años, 11 meses
Puntos: 28
Re: Asignacion dinamica de memoria

Yo lo probé con 6 números y me funcionó bien, el detalle es que esos "scanf("%c", &respuesta);" nunca me han gustado, siempre he creído que son una fuente de problemas.

Saludos

Agrego: Que no se te olvide liberar la memoria antes de que termine el programa, esta no es la causa de la falla, pero es un detalle importante.
__________________
Si crees que no tiene sentido, etonces probablemente lo tenga... :arriba:

Última edición por _Lucifer_; 25/03/2008 a las 12:02
  #3 (permalink)  
Antiguo 25/03/2008, 10:17
Avatar de Mephisto  
Fecha de Ingreso: enero-2006
Ubicación: Mexico DF
Mensajes: 184
Antigüedad: 18 años, 4 meses
Puntos: 3
Re: Asignacion dinamica de memoria

Por que no lo debuggeas para ver que no se esten encimando las localidades de memoria que se asignan en el realloc con algun otra variable del prog, esto pudiera ser una causa de que se te pierdan los valores... Mas considerando que a Lucifer si le funciono el código pudiera ser por lo que te menciono...
__________________
Saludos...

Todos somos sabios, solo que en diferentes disciplinas...
  #4 (permalink)  
Antiguo 25/03/2008, 15:18
 
Fecha de Ingreso: febrero-2003
Ubicación: D.F.
Mensajes: 163
Antigüedad: 21 años, 3 meses
Puntos: 22
Re: Asignacion dinamica de memoria

Saludos, el paso de parámetros por valor o por referencia aplica también a los punteros, en este caso el valor de 'vectororigen' no es modificado por la función leer_vector puesto que está siendo pasado por valor, un puntero doble resuelve el problema.

Otra cosa, evita el uso de fflush(stdin). (Buscando un poco en la red encuentras la explicación).
  #5 (permalink)  
Antiguo 26/03/2008, 07:25
Avatar de _Lucifer_  
Fecha de Ingreso: junio-2006
Mensajes: 1.662
Antigüedad: 17 años, 11 meses
Puntos: 28
Re: Asignacion dinamica de memoria

Cita:
Iniciado por fightmx Ver Mensaje
...
el paso de parámetros por valor o por referencia aplica también a los punteros, en este caso el valor de 'vectororigen' no es modificado por la función leer_vector puesto que está siendo pasado por valor, un puntero doble resuelve el problema.
...
Si eso es verdad, ¿cómo me funcionó a mi?

Saludos
__________________
Si crees que no tiene sentido, etonces probablemente lo tenga... :arriba:
  #6 (permalink)  
Antiguo 26/03/2008, 12:12
 
Fecha de Ingreso: febrero-2003
Ubicación: D.F.
Mensajes: 163
Antigüedad: 21 años, 3 meses
Puntos: 22
Re: Asignacion dinamica de memoria

Buena pregunta Lucifer, aparentemente todo funciona como se espera, aunque muy en el fondo este caso es algo particular, cada vez que se invoca realloc estamos reasignando nuestro bloque de memoria, este nuevo bloque puede o no coincidir con la posición del bloque que teniamos previamente reservado, esto en realidad como tal no lo controlamos. Ahora, lo que esta sucediendo aquí es que el bloque de memoria que estamos reasignado sigue conservando la misma posición inicial en memoria que el bloque de origen y esto ha permitido que el puntero "vectororigen" siga apuntando al mismo, lo cual no significa que este bien.

Un simple cambio en el código puede dejar ver el error, ya que realloc reubicará el bloque en memoria:
Código:
void leer_vector(int *vect, int *n)
{
	int i=0;
	char respuesta;
	int nuevo_tamano=0;
	int *ptr = malloc(sizeof *ptr);

	do
	{
		fflush(stdin);
		printf("\n¿Elemento %d del vector origen?", i+1);
		scanf("%d", &vect[i]);
		fflush(stdin);
		printf("\n¿Otro elemento?(S/N)");
		scanf("%c", &respuesta);
		if (respuesta=='s' || respuesta=='S')
		{
			nuevo_tamano = sizeof(int)*(i+2);
			vect = (int *) realloc (vect, nuevo_tamano );
			i++;
		}
		*n = i+1;

	}while(respuesta=='s' || respuesta=='S');
}
Otra cosa Carlos2005 cada vez que utilices malloc o realloc incluye stdlib.h.

Un Saludo.
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 04:30.