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

Duda con punteros

Estas en el tema de Duda con punteros en el foro de C/C++ en Foros del Web. Hola a todos. Tengo que hacer una práctica para la universidad y no consigo entender bien el funcionamiento de los punteros, antes que nada quiero ...
  #1 (permalink)  
Antiguo 31/03/2010, 08:46
 
Fecha de Ingreso: enero-2007
Mensajes: 8
Antigüedad: 17 años, 3 meses
Puntos: 0
Exclamación Duda con punteros

Hola a todos.
Tengo que hacer una práctica para la universidad y no consigo entender bien el funcionamiento de los punteros, antes que nada quiero aclarar que no busco que andie me haga el ejercicio, sencillamente porque son muchas cosas y llevaría su tiempo, además a mi me gusta programar xD.

Bueno empecemos:

Tengo una preciosa clase llamada ListaInvestigadores, que como habeis acertado se trata de un vector de punteros que apunta a objetos del tipo Investigador, a que mola!

Código:
class ListaInvestigadores
{
    public:
        ListaInvestigadores();
        Investigador get(unsigned pos);
        void insertar(Investigador i);
        void eliminar(unsigned pos);
        void set(unsigned pos, Investigador i);
        int size();
        string toString();
    private:
        int s;
        Investigador *l;
        Investigador **lArr;
};
Bueno, ahora mismo estoy programando el método insertar, me parece que es por lo que hay que empezar.

lo que tendría que hacer, si no estoy equivocado es:

crear un array nuevo de punteros que se de tamaño s(numero de elementos) + 1, copiar los elementos del array antiguo y agregar la direccion del investigador que me pasan al final de todo, para terminar debo decirle a lArr que apunte al array nuevo para sustituirlo.

Tengo unas dudas.

1. La mas importante, lo que he hecho y programado es lo mismo.
2. Cuando finaliza el método no debería borrar las variables declaradas dentro de él, con esto me refiero a que el array nuevo debería desaparecer y por consiguiente, la dirección que apunta lArr al final, no debería apuntar a nada?

Ahora os dejo el código de lo que he implementado:

PD: Teneis libertad de criticarlo todo lo que querais.

Código:
void ListaInvestigadores::insertar(Investigador i)
{
    Investigador **lArrNuevo;
    lArrNuevo = new Investigador * [s+1];
    if(lArrNuevo == 0)
        cout << "Ha sucedido un problema al crear el puntero lArrNuevo";
    else
    {
        for(int j=0; j < s; j++)
            lArrNuevo[j] = lArr[j];
        lArrNuevo[s] = &i;
        cout << lArrNuevo[s]->toString();
        s++; // Incrementamos en 1 el numero de Investigadores
        lArr = lArrNuevo;
    }
}
Gracias a todos lo que os paseis por aquí y dediqueis 5 min a leer este tostón.

Saludos, Eduardo
  #2 (permalink)  
Antiguo 31/03/2010, 11:08
 
Fecha de Ingreso: junio-2008
Ubicación: Seattle, USA
Mensajes: 733
Antigüedad: 15 años, 10 meses
Puntos: 61
Respuesta: Duda con punteros

Si tu arreglo mantiene punteros a Investigadores, el metodo deberia recibir eso, punteros. Si no recibe punteros, entonces recibira una copia de los objetos que te pasan, tal como estas declarando el metodo, y al asignarle a tu arreglo mediante

lArrNuevo[s] = &i;

estas guardando la direccion de memoria de una copia, copia que morira al salir del metodo.
En este caso, lo que deberias hacer es pedir memoria para un investigador, copiar los datos de lo que te pasan, y olvidarte de la copia. Pero esto parece mas trabajo que simplemente guardar punteros a objetos que fueron creados en otro lugar.

Esta el problema de la propiedad. Quien es el dueño de la memoria que ahora guardas en esos punteros? Si es el usuario externo de la clase, el se tiene que preocupar de liberar esa memoria, y si es esta coleccion, ella tiene que liberar la memoria en el destructor.

Por otro lado, la memoria que antes fue pedida para el arreglo lArr, no la estas liberando y lo tienes que hacer antes de la asignacion

lArr = lArrNuevo;

o si no, habras perdido la direccion que permitira tal liberacion.
  #3 (permalink)  
Antiguo 31/03/2010, 11:49
 
Fecha de Ingreso: enero-2007
Mensajes: 8
Antigüedad: 17 años, 3 meses
Puntos: 0
De acuerdo Respuesta: Duda con punteros

Hola CalgaryCorpus.

Gracias por tu comentario, lo de liberar lArr lo sabía, pero como recien estoy haciendo la aplicación, prefiero probar el código y una vez que funciona, agrego lo que falta.

Respecto a:
Cita:
Si tu arreglo mantiene punteros a Investigadores, el metodo deberia recibir eso, punteros. Si no recibe punteros, entonces recibira una copia de los objetos que te pasan, tal como estas declarando el metodo, y al asignarle a tu arreglo mediante
La cabecera de la función tendría que ser:

void ListaInvestigadores::insertar(Investigador *i)

y lo demás tendría que dejarlo igual, no?

Código:
void ListaInvestigadores::insertar(Investigador *i)
{
    Investigador **lArrNuevo;
    lArrNuevo = new Investigador * [s+1];
    if(lArrNuevo == 0)
        cout << "Ha sucedido un problema al crear el puntero lArrNuevo";
    else
    {
        for(int j=0; j < s; j++)
            lArrNuevo[j] = lArr[j];
        lArrNuevo[s] = &i;
        cout << lArrNuevo[s]->toString();
        s++; // Incrementamos en 1 el numero de Investigadores
        delete[] lArr;
        lArr = lArrNuevo;
    }
}
podrás ver que he agregado el delete[] lArr.

Este código funciona si esta en el menú principal, pero ahora lo he encapsulado dentro de un procedimiento para tener todo ordenado y falla, me sale una ventana de ensamblador, lo que me imagino que es lo que tu dices, algo en la memoria falla.

Gracias

-------------------------------------------------------------

Ya que ahora lo que le paso es un puntero:

lArrNuevo[s] = &i;

Debería pasar a:

lArrNuevo[s] = i;

Ya que se va a hacer una copia binaria de i, la cual contiene la dirección de memoria dónde se encuentra el objeto investigador y esa direccions e asignara a la posicion s de iArrNuevo ¿Esto sería correcto?

Ahora tengo el procedimiento nuevo:

Código:
void altaInvestigador(ListaInvestigadores l)
{
    Investigador *i;
    i->set();
    l.insertar(i);
}
El problema es que ahora el metodo set falla...

Última edición por eduardor2k; 31/03/2010 a las 11:57
  #4 (permalink)  
Antiguo 31/03/2010, 12:16
 
Fecha de Ingreso: junio-2008
Ubicación: Seattle, USA
Mensajes: 733
Antigüedad: 15 años, 10 meses
Puntos: 61
Respuesta: Duda con punteros

No puedes invocar metodos de objetos que no existen.
Si defines i asi:

Investigador *i;

aun no tienes a ningun investigador. Solo tienes una variable que podria apuntar alguna vez a algun investigador.
Al hacer

i->set()

vas al investigador, apuntado por i, y llamas el metodo set() de el. Pero i no apuntaba a ninguno, al menos no le has dicho al programa que apunte a alguno.
  #5 (permalink)  
Antiguo 31/03/2010, 12:28
 
Fecha de Ingreso: enero-2007
Mensajes: 8
Antigüedad: 17 años, 3 meses
Puntos: 0
Respuesta: Duda con punteros

Cita:
Iniciado por CalgaryCorpus Ver Mensaje
No puedes invocar metodos de objetos que no existen.
Si defines i asi:

Investigador *i;

aun no tienes a ningun investigador. Solo tienes una variable que podria apuntar alguna vez a algun investigador.
Al hacer

i->set()

vas al investigador, apuntado por i, y llamas el metodo set() de el. Pero i no apuntaba a ninguno, al menos no le has dicho al programa que apunte a alguno.
Muchas gracias, que burrada hice, lo peor es que ni siquiera me he dado cuenta.

Bueno, gracias a tu ayuda, ahora ya no rompe al momento de agregar valores a las variables del objeto, creo que esto último me tendría que haber dado una pista de dónde estaba el problema.

Código:
void altaInvestigador(ListaInvestigadores l)
{
    Investigador *i = new Investigador();
    i->set();
    l.insertar(i);
}
Pero ahora me falla al asignar el puntero lArr = lArrNuevo ? Se trata de una copia binaria y no debería dar error?¿

Código:
void ListaInvestigadores::insertar(Investigador *i)
{
    Investigador **lArrNuevo;
    lArrNuevo = new Investigador * [s+1];
    if(lArrNuevo == 0)
        cout << "Ha sucedido un problema al crear el puntero lArrNuevo";
    else
    {
        for(int j=0; j < s; j++)
            lArrNuevo[j] = lArr[j];
        lArrNuevo[s] = i;
        cout << lArrNuevo[s]->toString();
        s++; // Incrementamos en 1 el numero de Investigadores
        delete[] lArr;
        lArr = lArrNuevo;
    }
}
Dejo todo el código cambiado por si a alaguien más le es útil, ya que está todo explciado en este post.

Muchas gracias CalgaryCorpus, creo que esto lo dejo por hoy y sigo mañana.

Última edición por eduardor2k; 31/03/2010 a las 12:48

Etiquetas: punteros
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 10:10.