-1

I'm pretty sure my problem is a memory related one, and even though I have searched for other people's solutions, I haven't had any luck.

Here's the code:

#include <iostream>
#include <fstream>
#include <cstdlib>
#include <cstring>

using namespace std;

typedef string tElemLista;

typedef struct nodo {
    tElemLista title;
    tElemLista info; // el elemento en sí
    nodo *next; // puntero autoreferencial
    nodo *prev;
    // al proximo nodo
} tNodo;

class tLista {
    tNodo *head;
    tNodo *tail;
    tNodo *curr;
    unsigned int listSize;
    unsigned int pos; // posición actual en la lista
public:
    tLista() {
        head = tail = curr = NULL;
        listSize = 0; // lista vacía
        pos = 0;
    }
    void Clear(){
        tNodo * temp;
        moveToStart();
        while (listSize!=0){
            temp = curr;
            moveToNext();
            free(temp);
            listSize--;
        }

        head = tail = curr = (tNodo *)malloc(sizeof(tNodo));
        listSize = 0; // lista vacía
        pos = 0;

    }
    int Insert(){
        tNodo * temp;

        if (listSize == 0){
            head = tail = curr = (tNodo *)malloc(sizeof(tNodo));
            curr->next = curr->prev = NULL;
            listSize++;
        }
        else if (curr == tail){
            curr->next = (tNodo *)malloc(sizeof(tNodo));
            curr->next->prev = curr;
            if (curr == tail){
                tail = curr->next;
            }
            listSize++;
        }
        else{
            temp = curr->next;
            curr->next = (tNodo *)malloc(sizeof(tNodo));
            curr->next->prev = curr;
            curr->next->next = temp;
            temp->prev = curr->next;
            listSize++;
        }
        return pos;
    }
    int append(tElemLista item){
        unsigned int temp = pos;
        moveToEnd();
        Insert();
        moveToPos(temp);
        return pos;
    }
    tElemLista Remove(){
        tNodo * borrar;
        tElemLista retorno = curr->info;
        if (listSize == 1){
            free(curr);
            head = tail = curr = NULL;
            listSize = 0;
        }
        else if(curr == head){
            borrar = curr;
            head = head->next;
            if (head == NULL){
                tail = NULL;
            }
            else{
                curr = head;
                head->prev = NULL;
            }
            listSize--;
            free(borrar);
        }
        else if(curr == tail){
            borrar = curr;
            tail = tail->prev;
            if (tail == NULL){
                head = NULL;
            }
            else{
                curr = tail;
                tail->next = NULL;
            }
            listSize--;
            pos--;
            free(borrar);
        }
        else{
            borrar = curr;
            curr->prev->next = curr->next;
            curr->next->prev = curr->prev;
            listSize--;
            free(borrar);
        }
        return retorno;
    }

    void moveToStart(){
        curr = head;
        pos = 0;
    }
    void moveToEnd(){
        curr = tail;
        pos = listSize;
    }
    void moveToNext(){
        if (curr != tail){
            //cout<< "\n\n" << curr->next<< "\n\n\n";
            curr = curr->next;
            pos++;
        }
    }
    void moveToPrev() {
        if (curr != head){
            curr = curr->prev;
            pos--;
        }
    }

    int length(){
        return listSize;
    }
    int currPos(){
        return pos;
    }
    void moveToPos(unsigned int to){
        while (to != pos){
            if (to > pos){
                moveToNext();
            }
            else{
                moveToPrev();
            }
        }
    }
    tElemLista getValue(){
        return curr->info;
    }
    tElemLista setValue(tElemLista input){
        tElemLista antiguo;
        //cout << input <<"\n";
        curr->info = input;
        return antiguo;
    }
    tElemLista getTitle(){
        return curr->title;
    }
    tElemLista setTitle(tElemLista input){

        tElemLista antiguo;

        //cout << curr->title <<"\n";
        //cout << input <<"\n";
        //cout << "OO";
        curr->title = input;
        //cout << curr->title <<"\n";
        return antiguo;
    }

};


int main(){
    string linea_input; //El profesor Arroyuelo nos dijo que podíamos usar string de STL.
    string comando;
    string info;
    string opened_output;

    tLista Presentacion;

    fstream archivo_input("input.txt");
    fstream archivo_output;

    if (!archivo_input.is_open()){
        perror("Error al abrir input.txt");
        return 1;
    }

    while(!archivo_input.eof()){
        getline(archivo_input, linea_input);

        size_t found;
        if ((found = linea_input.find(" ")) != string::npos){
            comando = linea_input.substr(0,found);
            info = linea_input.substr(found+1, string::npos);

            if (comando == "NUEVA_PRESENTACION"){
                info.append(".txt");
                Presentacion.Insert();
                //cout << info;
                opened_output = info;
                archivo_output.open(opened_output.c_str()); //Crear archivo
            }
            else if (comando == "CARGAR_PRESENTACION"){

            }

            else if (comando == "SET_CONTENIDO"){

                Presentacion.setValue(info);
            }
            else if (comando == "SET_TITULO"){
                //cout << "HM";
                Presentacion.setTitle(info);
            }




        }
        else{
            if (linea_input == "NUEVA_DIAPOSITIVA"){

                Presentacion.Insert();
                //cout << "UNOVA\n";
            }
            else if (linea_input == "VER_DIAPOSITIVA"){
                cout << "Posicion: " << Presentacion.currPos();
                cout << " - Titulo: " << Presentacion.getTitle();
                cout << " - Contenido: " << Presentacion.getValue() << "\n";
            }
            else if (linea_input == "SIGUIENTE"){
                Presentacion.moveToNext();
            }
            else if (linea_input == "ANTERIOR"){
                Presentacion.moveToPrev();
            }
            else if (linea_input == "ELIMINAR_DIAPOSITIVA"){
                Presentacion.Remove();
            }
            else if (linea_input == "GUARDAR"){
                unsigned int temp_pos = Presentacion.currPos();
                Presentacion.moveToStart();
                archivo_output << "DIAPOSITIVA #" << Presentacion.currPos() << "\n";

                archivo_output << Presentacion.getTitle() << "\n";
                archivo_output << Presentacion.getValue() << "\n";

                while(Presentacion.currPos() != Presentacion.length()- 1){

                    Presentacion.moveToNext();
                    archivo_output << "DIAPOSITIVA #" << Presentacion.currPos() << "\n";
                    archivo_output << Presentacion.getTitle() << "\n";
                    archivo_output << Presentacion.getValue() << "\n";
                    archivo_input.close();
                    archivo_input.open(opened_output.c_str());
                }
                Presentacion.moveToPos(temp_pos);
            }
            else if (linea_input == "SALIR"){
                Presentacion.Clear();
                return 0;
            }
        }
        /*
        if(linea_input.npos != pos_corte) {
            comando = comando.substr(pos_corte + 1);
            linea_input = linea_input.substr(0, pos_corte);
        }
        */
        //cout << linea_input << "\n";
        //cout << comando << "\n";


        //cout << comando << "\n";
    }

    archivo_input.close();
    return 0;
}

Any help?

EDIT: Here's the input.txt file:

NUEVA_PRESENTACION TAAA
SET_TITULO titulo 1
SET_CONTENIDO blah blah blah
SET_CONTENIDO blah
VER_DIAPOSITIVA
GUARDAR
SALIR
jps
  • 20,041
  • 15
  • 75
  • 79
  • When you run this code in a debugger, at what line does the segfault occur? – Drew Dormann May 15 '15 at 21:30
  • `and even though i have searched for other people's solutions, i haven't had any luck.` You're wasting time if that's how you believe you will solve your problem. Programming is not a math exercise, where there is a "solution" you can plug in (unless you copy their functions and code). You have to debug your code to figure out what's wrong. The odds that someone coded the exact same functions, with the exact same lines of code as you have, is close to 0. – PaulMcKenzie May 15 '15 at 21:33
  • 2
    Also, you should have tested this class before doing any sort of file I/O. You are opening a file, and we have no idea what data you used. Please post a few lines of sample data that duplicates the issue. – PaulMcKenzie May 15 '15 at 21:37
  • @drew-dormann 229 and 180, which means it has something to do of how i assign curr->title = input. – Eduardo Quezada May 15 '15 at 21:44
  • Added the input file – Eduardo Quezada May 15 '15 at 21:47
  • 1
    @EduardoQuezada Why are you using `malloc` in a C++ program. It is more than likely the reason for your issues. – PaulMcKenzie May 15 '15 at 21:48

1 Answers1

5

First, you should have written a very small test program before inundating yourself with all sorts of file I/O and other things that are not important.

I took your code, and created the following 3 line main program (I am using Visual C++ 2013):

int main()
{
    tLista myList;
    myList.append("abc");
    myList.append("123");  // < -- hangs here
}

This is what you should have started with and tested.

This is all I needed to duplicate one major issue with your code. The issue is here:

    head = tail = curr = (tNodo *)malloc(sizeof(tNodo));

You cannot use malloc to create the tNodo object. That class contains a std::string member, meaning that it is not a POD type.

You cannot instantiate non-POD types using malloc (unless later you are using placement-new). You must use new to dynamically create the object.

    head = tail = curr = new tNodo();

You make the same error in other parts of the code.

This is only one obvious error. You may have others, so I suggest you scrap your main program for now and write simple tests as I did above.

More info on POD types: What are POD types in C++?

Community
  • 1
  • 1
PaulMcKenzie
  • 34,698
  • 4
  • 24
  • 45
  • Thank you! That solved it for now. I'm going to make lots of tests now, to check if there's any other ones. I guess needed to test it more than i did, then. – Eduardo Quezada May 15 '15 at 21:57