0

That's the code:

#include <iostream>
#include <string.h>
using namespace std;
class List;

class Node{
    char data;

public:
    Node(char d):data(d),next(NULL){} // INICIALIZAÇÃO CONHECIDA COMO: inicialization list
    Node* next;
    char getData(){
        return data;
    }
    ~Node(){
        if(next!=NULL){
            delete next; // é tipo uma chamada recursiva, vai deletando tudo.
        }
    }
    friend class List;
};

class List{
    Node * head;
    Node * tail;

public:

    Node * begin(){
        return head;
    }
    List():head(NULL),tail(NULL){}
    void push_front(char  data){
        if(head == NULL){
            Node * n = new Node(data);
            head = tail = n;
        }
        else{
            Node * n = new Node(data);
            n->next = head;
            head = n;
        }
    }
    void push_back(char data){
        if(head==NULL){
            Node * n = new Node(data);
            head = tail = n;
        }else{
            Node * n = new Node(data);
            tail->next = n;
            tail = n;
        }
    }
    void insert(char data, int pos){
        if(pos==0){
            push_front(data);
            return;
        }
        Node* temp = head;
        for(int jump = 1; jump <=pos-1;jump++){
            temp = temp->next;
        }
        Node *n = new Node(data);
        n->next = temp->next;
        temp->next = n;
    }

    ~List(){
        if(head!=NULL){
            delete head;
            head = NULL;
        }
    }
};

int main()
{

    List l;
    int i=0;
    char temp;
    char str[10000];
    int posx=0;

    while(scanf("%s", str) != '\0'){
        while(str[i] != '\0'){
                temp = str[i];
            if(str[i] == '['){
                while(str[i+1] != ']' && str[i+1] != '[' && str[i+1] != '\0'){

                    i++;
                    temp = str[i];
                    l.insert(str[i], posx);
                    posx++;
                }
            }else if(str[i] == ']'){
                while(str[i+1] != ']' && str[i+1] != '[' && str[i+1] != '\0'){
                    i++;
                    l.push_back(str[i]);
                }
            }else{
                l.push_back(str[i]);
            }
            i++;
            posx=0;
        Node *head = l.begin();
        while(head!=NULL){
            cout << head -> getData();
            head = head->next;
        }
        printf("\n");

        }


        i=0;
        l.~List();
    }

    return 0;
}

Being straight: The program gets a string, if the user types '[' the new characters (letters and underscores) will be added to the front, if the user inputs ']' then the cursor will move to the back.

The problem is: if I input [_text_[rinti]has[_the_]], before reaching has I have rinti_text_, and it's fine, but when it gets to has, the function push_back is called and it simply overwrites the word text, and after that I'll have rinti_has, instead of rinti_text_has. I do not know whats happening, but the problem seem to be with the function push_back. I would appreacite any hints or answers

  • 3
    Have you stepped through your code with a debugger? Problems like this are perfect use cases for learning to use your debugger. – Stephen Newell Mar 01 '22 at 22:11
  • @StephenNewell Yes, many times actually. What I have noticed is, function push_back is called, it adds the node, it changes the tail and the word text goes away. – Game changer Mar 01 '22 at 22:14
  • https://godbolt.org/z/fYsbK7dj1 looks like you deleted something that you access later. – mch Mar 01 '22 at 22:14
  • Is `tail` in the right place before `push_back` is called? – Stephen Newell Mar 01 '22 at 22:15
  • What do you want to do with `l.~List();`? never call a destructor explicitly. Also your destructor only handles `head`, but not `tail`. – mch Mar 01 '22 at 22:16
  • @StephenNewell it seems to be, before push_back is called the output is currently ```_rinti_text_```, the the tail points to "_" – Game changer Mar 01 '22 at 22:17
  • @mch I deleted the pop_back function, because I was not using it. – Game changer Mar 01 '22 at 22:18
  • @mch I wanted to free them, because I want more than 1 input. The program is meant to end with an "EOF" – Game changer Mar 01 '22 at 22:21
  • manually calling a destructor doesn't free anything. It just calls the destructor. This leaves you with a ball of memory with an invalid object in it, basically a grenade without a pin. Sooner or later, in this case it'll be when `l` goes out of scope and the program calls the destructor again, it'll go off and kablooey. Worst thing is you might not even see a visible failure and think, "Well! My code works!" – user4581301 Mar 01 '22 at 22:42
  • @user4581301 thank you, it was a really great answer. Do you have any hints how to do it correctly? – Game changer Mar 01 '22 at 22:46
  • You do nothing. `l` is an automatic variable. It resolves itself for you automatically. If your goal is to clear the list out either add a `clear` method that cleans up or tweak `List` to observe the [Rule of Three](https://en.cppreference.com/w/cpp/language/rule_of_three) (something you should do anyway to prevent other bugs) and `l = List();` to replace the current `List` with a new `List`. empty list You may find [Copy and Swap](https://stackoverflow.com/questions/3279543) helpful when writing the assignment operator. – user4581301 Mar 01 '22 at 22:55
  • Note: There are uses for calling the destructor yourself, but this is only needed for edge cases like complicated `union`s where you have to destroy the object currently in the `union` before changing the stored type and [placement new](https://en.cppreference.com/w/cpp/language/new#Placement_new). Probably a couple more viable uses but I've never run across them. – user4581301 Mar 01 '22 at 22:59

1 Answers1

1

The bug is in your insert function. If you try to insert at the end of your List, you never update tail. A simple solution without modifying your code too much is to check if temp is equal to tail and just call push_back directly.

This code seems to work on my system.

    void insert(char data, int pos){
        if(pos==0){
            push_front(data);
            return;
        }
        Node* temp = head;
        for(int jump = 1; jump <=pos-1;jump++){
            temp = temp->next;
        }
        if(temp == tail) {
            push_back(data);
        }
        else {
            Node *n = new Node(data);
            n->next = temp->next;
            temp->next = n;
        }
    }
Stephen Newell
  • 7,330
  • 1
  • 24
  • 28