Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: kur79 en 28 Octubre 2014, 19:00 pm



Título: Ayuda devolver un vector de una funcion
Publicado por: kur79 en 28 Octubre 2014, 19:00 pm
Buenas pues a ver, tengo un problema con un codigo y es que tengo una list<list<Peticion> > lista; y le inserto una Peticion correctamente en una funcion mediante iteradores y stl y demas, y durante la funcion compruebo haber añadido correctamente pero al abandonar la funcion en la que lo añado no se ha modificado y creo que habia que devolver algo pero no recuerdo qué exactamente. Mi funcion es un void a ver si alguien me podria decir qué debo carbiarle para que tire llevo ya mucho detras de este fallo y no lo logro.

Código:

void insertaEnLista(list<list<Peticion> > lista, Peticion p) {
 
    // CASO DE QUE LA LISTA ESTE TOTALMENTE VACIA, PARA EL PRIMER DATO QUE ENTRE
    if (lista.empty()) {
        cout << "La lista enlazada grande estaba vacia asi que le aniado la 1º" << endl;
        list<Peticion> l; //CREO UNA LISTA DE LAS QUE CUELGAN
        l.push_back(p); //l.push_front(p) LE METO LA PETICION
        lista.push_back(l); // A LA LISTA ENLAZADA GRANDE LE ANIADO UNA PEQUENIA
        cout << "Se ha introducido correctamente la peticion de codigo " << lista.begin()->begin()->getCodigo() << endl;
    } else {
        cout << "Aqui no entro porque la lista no esta vacia" << endl;
    }

    if (lista.empty()) {
        cout << "Comprobacion: esta vacia" << endl;
    } else {
        cout << "Comprobacion: no esta vacia" << endl;
    }

}


Título: Re: Ayuda devolver un vector de una funcion
Publicado por: avesudra en 28 Octubre 2014, 19:07 pm
Para aclararnos un poquito más y facilitarle la vida a los que te vamos a ayudar encierra tus códigos con la etiqueta GeSHi para ayudar a su correcta lectura así:
Código
  1. void insertaEnLista(list<list<Peticion> > lista, Peticion p)
  2. {
  3.    // CASO DE QUE LA LISTA ESTE TOTALMENTE VACIA, PARA EL PRIMER DATO QUE ENTRE
  4.    if (lista.empty())
  5.    {
  6.        cout << "La lista enlazada grande estaba vacia asi que le aniado la 1º" << endl;
  7.        list<Peticion> l; //CREO UNA LISTA DE LAS QUE CUELGAN
  8.        l.push_back(p); //l.push_front(p) LE METO LA PETICION
  9.        lista.push_back(l); // A LA LISTA ENLAZADA GRANDE LE ANIADO UNA PEQUENIA
  10.        cout << "Se ha introducido correctamente la peticion de codigo " << lista.begin()->begin()->getCodigo() << endl;
  11.    }
  12.    else
  13.        cout << "Aqui no entro porque la lista no esta vacia" << endl;
  14.  
  15.  
  16.    if (lista.empty())
  17.        cout << "Comprobacion: esta vacia" << endl;
  18.    else
  19.        cout << "Comprobacion: no esta vacia" << endl;
  20. }
El problema echandole un vistazo al código es que  estás pasando una lista por valor, esto hace que se copie toda la lista de una variable a otra y modificas ésta última, no la original, por tanto tu cambio no causa efecto en la original. Efectivamente es eso, te pongo como dirían los ingleses un "minimal working example" con enteros para que lo modifiques conforme a tus necesidades:
Código
  1. #include <iostream>
  2. #include <list>
  3.  
  4. using namespace std;
  5.  
  6. void insertaEnLista(list<list<int>> *lista, int p)
  7. {
  8.    // Si la lista está vacía de listas añado una lista nueva e inserto el elemento.
  9.    if (lista->empty())
  10.    {
  11.        list<int> listaTmp;
  12.        listaTmp.push_back(p);
  13.        lista->push_back(listaTmp);
  14.    }
  15.    // Si no está vacía añade p a la última lista.
  16.    else
  17.        (*--lista->end()).push_back(p);
  18. }
  19. int main(int argc, char** argv)
  20. {
  21.    list<list<int>> miLista = {{3,4},{2,3}};
  22.  
  23.    insertaEnLista(&miLista,7);
  24.  
  25.    for(list<list<int>>::iterator it = miLista.begin(); it != miLista.end(); ++it)
  26.        for(list <int>::iterator sit = (*it).begin(); sit != (*it).end(); ++sit)
  27.            cout << ' ' << *sit;
  28. }
Con la intención de poner más claro el programa he añadido un par de typedefs que acortan mucho los tipos que se suelen usar con las plantillas de C++:
Código
  1. #include <iostream>
  2. #include <list>
  3.  
  4. using namespace std;
  5.  
  6. typedef list<list<int>> iDList;
  7. typedef list<int> iList;
  8.  
  9. void insertaEnLista(iDList *lista, int p)
  10. {
  11.    // Si la lista está vacía de listas añado una lista nueva e inserto el elemento.
  12.    if (lista->empty())
  13.    {
  14.        iList listaTmp;
  15.        listaTmp.push_back(p);
  16.        lista->push_back(listaTmp);
  17.    }
  18.    // Si no está vacía añade p a la última lista.
  19.    else
  20.        (*--lista->end()).push_back(p);
  21.  
  22. }
  23. int main(int argc, char** argv)
  24. {
  25.    iDList miLista = {{3,4},{2,3}};
  26.  
  27.    insertaEnLista(&miLista,7);
  28.    for(iDList::iterator it = miLista.begin(); it != miLista.end(); ++it)
  29.        for(iList::iterator sit = (*it).begin(); sit != (*it).end(); ++sit)
  30.            cout << ' ' << *sit;
  31. }
Yendo al grano, tu problema es que tienes que pasar la lista por referencia para poder modificar la lista original y no una copia de ésta, asumo que si has llegado a listas te manejas con punteros, así que no debería haber problemas.

Un saludo.

Avesudra.