I have defined a print function in my main file. For what ever reason, if I call this function then my destructor appears to be called twice and then i get the "pointer being freed was not allocated" error
here is main
//sandbox.cc
//this file is for playing around with idea and modules
#include <iostream>
#include <string>
#include "list.hpp"
using namespace std;
void print_list(list L){
    const listNode* temp = L.getHead();
    while (temp != nullptr){
        cout << temp->index << endl;
        temp = temp->next;
    }
}
int main(int argc, char** argv)
{
  std::string buf("AABAABBBBCABBBBBBD");
  size_t LAB_index = 10;
  size_t max_match = 5;
  list ll = list(); 
  //all matches ar for AB
  ll.insert(1); 
  ll.insert(4);
  print_list(ll); //if you comment this line out there is no problem
  return 0;
}
here is header file for list
//list.hpp
#ifndef LIST_HPP
#define LIST_HPP
#include <stddef.h> //for size_t
#include <utility> //for std::pair
#include <string>
//A listNode is the core component in a list. its primary 
//function is to store an index into the input buffer
struct listNode{
        ////@: index into the input buffer
        listNode* next;
        size_t index;
};
//A list is a linked list composed of listNodes. It will be used by search buffer
//for to track all the occurences of character sequences
class list{
    private:
        //@:tail a pointer to listNode that is the tail of the list
        listNode* tail;
        //@:head a pointer to a listNode that is the head of the list
        listNode* head;
        //@:len is number of listNodes in the list
        size_t len;
    public:
        //#: inits list with head and tail pointing to null
        list( );
        //#: deletes each node in the list
        ~list();
        //@:i is an integer reprsenting an index 
        //#:will create a new list node with key set to i
        //#:and insert it at the end of the list. tail
        //#:points to this new element. and len incremented by one 
        void insert(size_t i);
        //#:removes the listNode pointed to by head 
        //#:and makes head point to the next of the recently
        //#:deleted head. Deletes the recently removed node
        void remove();
        //returns the list node pointed to by head
        const listNode* getHead();
        //@:LAB_index is the index where match begins in the LAB
        //@:L is the match length 
        //@:input_buf& is a reference to the input string buffer
        //
        //#:search the entire list for the ListNode
        //#:whose index when scanend has the longest match
        //#:up to L.
        //#:returns a pair where first entry is match index 
        //and the second is the length of the match
        //return a pair (0,0) if no match found
        std::pair<size_t,size_t> get_longest_match(size_t LAB_index,\
                                            size_t max_match,\
                                            const std::string& input_buf);
};
//SECTION: Helper Functions
//This function helps get_longest_match
//@:index specifies the index of the start of the match in the list
//@:L
//@:buf_index
//
//#:using brute force pattern matching, match as many characters
//#:as possible starting at matchindex+2 and buf_index+2 since
//#:these are assumed to have already been matched
//#:return the length of the match (include the two characters matched initially)
//#:thus lowest return value is 2
std::pair<size_t,size_t>  matchindex(size_t index,\
                   size_t LAB_index, size_t max_match,\
                   const std::string& input_buf);
#endif
here is implementation. please focus in particulart on the ~list. As you can see it will print "___" upon being invoked. When the print statement reffered to above in main is left uncommented, this line is printed twice. I am wondering why? And how can i get rid of this behavior?
#include "list.hpp"
#include <iostream>
list::list()
{
    head = nullptr;
    tail = nullptr;
    len = 0;
}
list::~list()
{
    listNode* temp = head ;
    std::cout << "____" << std::endl;
    while (temp != nullptr){
        listNode* node = temp->next;
        std::cout << temp->index << std::endl;
        delete temp;
        temp = node;
    }
    head = nullptr;
}
void list::insert(size_t i){
    if (head == nullptr){
        head = new listNode{nullptr,i};
        tail = head;
        ++len;
    }
    else{
        listNode* new_node = new listNode{nullptr,i};
        tail->next = new_node;
        tail = new_node;
    }
}
void list::remove()
{
    if (head != nullptr){
        listNode* new_head = head->next;
        delete head;
        head = new_head;
        --len;
    }
}
const listNode* list::getHead()
{
    return head;
}
std::pair<size_t,size_t> list::get_longest_match(size_t LAB_index,\
                                           size_t max_match,\
                                           const std::string& \
                                           input_buf)
{
    std::pair<size_t,size_t> match_pair(0,0), canidate_match;
    //Case1 no match
    if (head == nullptr)
        return match_pair;
    listNode* temp = head;
    while (temp != nullptr){
        canidate_match = matchindex(temp->index,\
                            LAB_index,max_match,input_buf);
        if (canidate_match.second > match_pair.second)
            match_pair = canidate_match;
        temp = temp->next;
    }
    return match_pair;
}
//SECTION: Helper Functions
std::pair<size_t,size_t> matchindex(size_t index,\
          size_t LAB_index,size_t max_match, const std::string& input_buf)
{
    std::pair<size_t,size_t> match_pair;
    size_t matchlength = 2;
    while (matchlength < max_match){
        if (input_buf[index] == input_buf[LAB_index]){
            ++matchlength;
            ++index;
            ++LAB_index;
        }
        else
            break;
    }
    match_pair = std::make_pair(index,matchlength);
    return match_pair;
}
