double free detected in tcache 2 when initializing a list, crashes upon entry insertion

Viewed 33

Reading from a file, each line is stored in a list as an individual row. Each row contains two standard values and a variable amount stored in a list. Therefore each node has two values and a list. Initialization through operator>> works, but as soon as I try to run the loadfile function it crashes with the error: free(): double free detected in tcache 2 Aborted (core dumped)

Here is the code

#include <iostream>
#include "Resource.h"
#include "list.h"
#include "node.h"

using std::cout;
using rows = List<Resource>;
using row = Node<Resource>;

void loadFile(string idata, rows &res)
{
    ifstream ifs(idata, ifstream::in);
    while (ifs.good())
    {
        Resource s;
        ifs >> s;
        row *temp = new Node<Resource>(s);
        res.insert(temp);
    }
    ifs.close();
}

int main()
{
    rows resList;
    loadFile("data.txt", resList);
    cout << resList.getHead()->getValue();
}

this is the source for the class that stores the values, that will be wrapped in a Node template class.

#ifndef RESOURCE_H
#define RESOURCE_H

#include <iostream>
#include <fstream>
#include <string>
#include "list.h"
#include "node.h"
#include <stdio.h>
#include <algorithm>

using std::cout;
using std::istream;
using std::string;

class Resource
{
private:
    string Name;
    int amt;
    List<string> clientList;

public:
    Resource(string n, int a) : Name(n), amt(a) {}
    Resource(string n) : Resource(n, 0) {}
    Resource() : Resource("", 0) {}

    string getName()
    {
        return this->Name;
    }
    int getAmt()
    {
        return this->amt;
    }
    void setName(string n)
    {
        this->Name = n;
    }
    void setAmt(int a)
    {
        this->amt = a;
    }
    friend ostream &operator<<(ostream &out, const Resource &r)
    {
        out << r.Name << ";" << r.amt;
        List<string> temp = r.clientList;
        for (Node<string> *app = temp.getHead(); app != NULL; app = app->getNext())
        {
            out << ';';
            out << app->getValue();
        }
        return out;
    }
    friend istream &operator>>(istream &in, Resource &r)
    {
        string Name;
        string amt;
        string params;
        string tempVar;
        getline(in, Name, ';');
        getline(in, amt, ';');
        getline(in, params, '\n');
        const int paramsOriginalLength = count(params.begin(), params.end(), ';');
        for (int i = 0; i < paramsOriginalLength; i++)
        {
            r.clientList.insert(params.substr(0, params.find(';')));
            params.erase(0, params.find(';') + 1);
        }
        r.setName(Name);
        r.setAmt(stoi(amt));
        return in;
    }
};

#endif

EDIT: Since the problem might be caused by the data structure's defintion I will include the source of list.h and node.h

List:

#ifndef LIST_H
#define LIST_H

// Standard Template Linked List - List - by Eduardo Meli - 2020

#include "node.h"
#include <iostream>
using namespace std;

template <class T>
class List
{
private:
    int length;
    Node<T> *head;

public:
    List(int length, Node<T> *head) : length(length), head(head) {}
    List() : List(0, NULL) {}

    Node<T> *getHead()
    {
        return this->head;
    }

    int getLength()
    {
        return this->length;
    }

    void insert(T value)
    {
        Node<T> *app = new Node<T>(value);
        this->insert(app);
    }

    void insert(Node<T> *n)
    {
        if (head == NULL)
        {
            head = n;
            length++;
            return;
        }
        Node<T> *curr = head;
        while (curr->getNext() != NULL)
        {
            curr = curr->getNext();
        }
        curr->setNext(n);
        length++;
    }

    void deleteNode(Node<T> *n)
    {
        if (n == this->getHead())
        {
            this->head = head->getNext();
            this->length = length - 1;
            delete n;
            return;
        }
        Node<T> *prev = head;
        Node<T> *curr = head->getNext();
        while (curr != NULL)
        {
            if (curr == n)
            {
                prev->setNext(curr->getNext());
                length--;
                return;
            }
            prev = curr;
            curr = curr->getNext();
        }
    }

    Node<T> *deleteNode(T value)
    {
        if (this->seekNode(value))
        {
            if (head->getValue() == value)
            {
                Node<T> *temp = head;
                head = head->getNext();
                length--;
                return temp;
            }
            Node<T> *prev = head;
            Node<T> *curr = head->getNext();
            while (curr != NULL)
            {
                if (curr->getValue() == value)
                {
                    prev->setNext(curr->getNext());
                    length--;
                    return curr;
                }
                prev = curr;
                curr = curr->getNext();
            }
        }
        return NULL;
    }

    void print()
    {
        Node<T> *nk = this->getHead();
        while (nk != NULL)
        {
            cout << nk->getValue() << endl;
            nk = nk->getNext();
        }
    }

    ~List()
    {
        Node<T> *ptr;

        for (ptr = head; head; ptr = head)
        {
            head = head->getNext();
            delete ptr;
        }
    }
};

#endif

And node:

#ifndef NODE_H
#define NODE_H

// Standard Template Linked List - Node - by Eduardo Meli - 2020


#include <fstream>
#include <iostream>
using namespace std;

template <class T>
class Node
{
private:
    T value;
    Node<T> *next;

public:
    Node(T value, Node<T> *next) : value(value), next(next) {}
    Node(T value) : Node(value, NULL) {}
    Node() : Node(0, NULL) {}
    T getValue()
    {
        return this->value;
    }
    Node<T> *getNext()
    {
        return this->next;
    }
    void setValue(T val)
    {
        this->value = val;
    }
    void setNext(Node<T> *n)
    {
        this->next = n;
    }
    friend ostream &operator<<(ostream &out, const Node &n)
    {
        out << n.value;
        return out;
    }
};

#endif
0 Answers
Related