1

here is my LinkedList implementation i am working on. it works fine for any data type but the problem arises when i try to make a Linked List of a type that have a linked list on debugging with visual studio i got Invalid address specified to RtlValidateHeap( 00790000, 007B16D0 )

the code looks like:

typedef unsigned long int LENGTH_T;
template < typename type >
struct nodes
{
    type _value;
    nodes<type> * _next_node;
    nodes() { _next_node = nullptr; }
};

template < typename type >
class LinkedList
{
    nodes<type> * _elem_nodes;
    LENGTH_T _size;
public:
    nodes<type> * node_at(LENGTH_T at);
    type& operator[] (LENGTH_T at);
    void push_back(const type src);
    LENGTH_T size() const { return _size; }
    LinkedList();
    ~LinkedList();
};

template<typename type>
nodes<type>* LinkedList<type>::node_at(LENGTH_T at) {
    if (at == 0)
        return _elem_nodes;
    else if (at > _size - 1 || _size == 0) {
        PRINT_ERROR("try to access out of range");
    }

    // tmp node for storing sequential nodes
    nodes<type> * cur_tmp_node_ptr = _elem_nodes->_next_node;

    for (size_t i = 1; i < at; i++)
        cur_tmp_node_ptr = cur_tmp_node_ptr->_next_node;

    return cur_tmp_node_ptr;
}

template<typename type>
type & LinkedList<type>::operator[](LENGTH_T at)
{
    return node_at(at)->_value;
}

template<typename type>
void LinkedList<type>::push_back(const type src)
{
    if (_size == 0) {
        _elem_nodes->_value = src;
        _size++;
    }
    else {
        nodes<type> * new_node = new nodes<type> ;
        new_node->_value = src;
        new_node->_next_node = nullptr;
        node_at(_size - 1)->_next_node = new_node;
        _size++;
    }
}

template<typename type>
LinkedList<type>::LinkedList()
{
    _size = 0;
    _elem_nodes = new  nodes<type>;
    _elem_nodes->_value = type();
    _elem_nodes->_next_node = nullptr;
}

template<typename type>
LinkedList<type>::~LinkedList()
{
    if (_size > 1) // When size = 0 , so _size-1 = -1 but _size is unsigned;
        for (LENGTH_T i = _size - 1; i > 0; i--) {
            delete ( node_at(i) );
        }
    delete ( _elem_nodes );
}

here is an example of code in which specified problem can be observed f.e

struct test {
    int anything;
};

struct test2 {
    LinkedList<test> t;
};

int main()
{
    LinkedList<test2> t;
    t.push_back(test2());
    t.push_back(test2());
    return 0;
} 

**EDIT: I wrote Custom Assignment operator and Copy constructor and not getting that error anymore but in the above example in test2().t._next_node always contains junk values rather then nullptr which i am not understanding why **

template<typename type>
LinkedList<type>& LinkedList<type>::operator=(const LinkedList<type>& other )
{
    if (&other == this)
        return *this;
    this->~LinkedList();
    this->_elem_nodes = nullptr;
    _size = 0;
    nodes<type> * cur_this_node = this->_elem_nodes;
    nodes<type> * cur_other_node = other._elem_nodes;
    while (cur_other_node != nullptr)
    {
        cur_this_node = new nodes<type>;
        cur_this_node->_value = cur_other_node->_value;
        this->_size++;
        cur_this_node = cur_this_node->_next_node;
        cur_other_node = cur_other_node->_next_node;
    }
    return *this;
}

template<typename type>
LinkedList<type>::LinkedList(const LinkedList<type>& other)
{
    _size = 0;
    nodes<type> * cur_this_node = this->_elem_nodes;
    cur_this_node = nullptr;
    nodes<type> * cur_other_node = other._elem_nodes;
    while (cur_other_node != nullptr)
    {
        cur_this_node = new nodes<type>;
        cur_this_node->_value = cur_other_node->_value;
        cur_this_node->_next_node = nullptr;
        this->_size++;
        cur_this_node = cur_this_node->_next_node;
        cur_other_node = cur_other_node->_next_node;
    }
}
bluedragon
  • 630
  • 6
  • 17

1 Answers1

0

You have a rule of three (or four or five) violation. You've defined a custom destructor, but not a custom assignment operator. In your case, this ends up causing two separate LinkedList objects to point to the same nodes.

More info: https://stackoverflow.com/a/4782927/951890

Vaughn Cato
  • 59,967
  • 5
  • 75
  • 116
  • i wrote the custom assignment operator but still got the same error please check that at first post, i edited that with the implementation of that – bluedragon Jun 10 '17 at 16:48
  • @bluedragon: You also are missing a copy constructor. – Vaughn Cato Jun 10 '17 at 17:01
  • okay i successfully(?) wrote that and it works i don't get that error but in example object created by test2() always contains null value rather then nullptr and hence my loop goes infinite, so for late replies i am still a novice – bluedragon Jun 10 '17 at 17:57