Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

I'm having difficulty fixing what I believe to be a double free

Tags:

c++

I'm trying to create a vector of linked lists as a class member. Valgrind shows that there are no memory leaks, but also produces Invalid free() / delete / delete[] / realloc() errors on program end.

I've tried to fix this by writing a destructor, copy constructor, and copy assignment operator for the linked list. I believe these have been implemented correctly. I've also tried various methods of adding linked lists to the member vector (references, pointers, smart pointers), none of which seem to solve the problem.

#include "lists.h"

lists::lists() {

}

void lists::newList() {
  int size, value;
  cout << "Please specify size of this list" << endl;
  cin >> size;
  shared_ptr<list> new_list(new list);
  //list *new_list = new list();
  for (int i = 0; i < size; i++) {
    cout << "Enter value for node " << i + 1 << endl;
    cin >> value;
    new_list->pushBack(value);
  }
  list_storage.push_back(new_list);
  //delete new_list;
}

void lists::deleteList() {

}

void lists::display() {
  for (int i = 0; i < list_storage.size(); i++) {
    list_storage[i]->display();
  }
}

#include "list.h"

list::list() {
  head = NULL;
}

list::list(const list& list) {
  head = NULL;
  node *current = head;
  while (current != NULL) {
    this->pushBack(current->data);
    current = current->next;
  }
}

list& list::operator=(const list& rhs) {
  list temp(rhs);
  swap(temp.head, head);
  return *this;
}

list::~list() {
  if (head != NULL) {
    node *current = head;
    while (current != NULL) {
      node *next = current->next;
      delete current;
      current = next;
    }
    delete head;
  }
}

Here's the valgrind output:

==15967== Invalid free() / delete / delete[] / realloc()
...
==15967== HEAP SUMMARY:
==15967==     in use at exit: 0 bytes in 0 blocks
==15967==   total heap usage: 9 allocs, 10 frees, 74,856 bytes allocated
==15967== 
==15967== All heap blocks were freed -- no leaks are possible
==15967== 
==15967== For counts of detected and suppressed errors, rerun with: -v
==15967== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
like image 430
learningthings Avatar asked Dec 18 '22 17:12

learningthings


1 Answers

Have a look at your destructor :

list::~list() {
  if (head != NULL) {
    node *current = head;
    while (current != NULL) {
      node *next = current->next;
      delete current;
      current = next;
    }
    delete head;
  }
}

entering the loop, you delete current, which is head at first iteration. After the loop you delete head again -> double free.

like image 200
Regis Portalez Avatar answered May 30 '23 18:05

Regis Portalez