Wycieki pamieci wskazniki shared_ptr lista dwukierunkowa

0

Witam, cwicze działanie wskaznikow unique oraz shared w C++.
Bawie sie na takiej oto liscie dwukierunkowej.
Pierwszy program to lista 1 kierunkowa, analizuje go valgrindem i wszystko jest ok (shared_ptr sprzątają po sobie) :

#include <iostream>
#include <memory>
#include <stdexcept>

using namespace std;



class EmptyListError : public std::runtime_error
{
public :
	EmptyListError(std::string msg) :
           runtime_error(msg)
	{}
};



class NotFoundError : public std::runtime_error
{
public :
	NotFoundError(std::string msg) :
           runtime_error(msg)
	{}
};





class Node
{
public:
    Node(const int v) :
        next(nullptr),
        value(v)
    {}


  
    std::shared_ptr<Node> next;
    int value;

   
};

class List
{
public:
    List();
    
    void add(shared_ptr<Node> node);        // dodaje element na koniec listy
    shared_ptr<Node> get(const int value);  // zwraca element o wskazanej wartości

private:
    shared_ptr<Node> first;
};


List::List() :
	first(nullptr)
{}


void List::add(shared_ptr<Node> node)
{
   if(node->next)
    {
	cerr<< "Nie można dodać ponownie tego samego węzła" << endl;
	return;	
    }
 

    if(!first)
    {
        first = node;
    }
    else
    {
        shared_ptr<Node> current = first;
        while(current->next)
        {
		
            current = current->next;
		
        }
       
        current->next = node;
	
		
    }
}

shared_ptr<Node> List::get(const int value)
{
    if(!first)
    {
        throw EmptyListError("Lista jest pusta !");
    }
    else
    {
        shared_ptr<Node> current = first;
        do
        {
            if(current->value == value)
            {
                cout << "Found value " << current->value << endl;
                return current;
            }
            else
            {
                cout << "Going through " << current->value << endl;
	
                     current = current->next;
            }
        } while(current);

	throw NotFoundError("Not found");
        //cout << "Not found: value " << value << endl;
	
        return nullptr;
    }
}

int main()
{
    List lista;




    
    auto node4 = make_shared<Node>(4);
    auto node7 = make_shared<Node>(7);

   
    lista.add(node4);
    lista.add(make_shared<Node>(2));
    lista.add(node4);
    lista.add(make_shared<Node>(9));
    lista.add(node7);

    try {
       auto node= lista.get(11);
	}
	catch(EmptyListError & e) {
		cout << e.what() <<endl;
	}
	catch(NotFoundError & e){
		cout<<e.what()<<endl;		
	}
		

  



    return 0;
}
 

Teraz przerobiłem tą liste na dwukierunkową, kod ponizej. Pytanie co jest nie tak tutaj, bo wg valgrinda : total heap usage: 1 allocs, 0 frees, 64 bytes allocated, czyli coś nie sprząta po sobie, pytanie dlaczego. ?
KOD :

 #include <iostream>
#include <memory>
#include <stdexcept>

using namespace std;



class EmptyListError : public std::runtime_error
{
public :
	EmptyListError(std::string msg) :
           runtime_error(msg)
	{}
};



class NotFoundError : public std::runtime_error
{
public :
	NotFoundError(std::string msg) :
           runtime_error(msg)
	{}
};





class Node
{
public:
    Node(const int v) :
        next(nullptr),
	prev(nullptr),
        value(v)
    {}


  
    std::shared_ptr<Node> next;
    std::shared_ptr<Node> prev;
    int value;

   
};



class List
{
public:
    List();
    
    void add(shared_ptr<Node> node);        // dodaje element na koniec listy
    shared_ptr<Node> get(const int value);  // zwraca element o wskazanej wartości

private:
    shared_ptr<Node> first;
};


List::List() :
	first(nullptr)
{}



void List::add(shared_ptr<Node> node)
{
   if(node->next)
    {
	cerr<< "Nie można dodać ponownie tego samego węzła" << endl;
	return;	
    }
 

    if(!first)
    {
        first = node;
	node->prev=first;
    }
    else
    {
        shared_ptr<Node> current = first;
        while(current->next)
        {
		
            current = current->next;
		
        }
       
        current->next = node;
	node->prev=current;      
	
		
    }
}



shared_ptr<Node> List::get(const int value)
{
    if(!first)
    {
        throw EmptyListError("Lista jest pusta !");
    }
    else
    {
        shared_ptr<Node> current = first;
        do
        {
            if(current->value == value)
            {
                cout << "Found value " << current->value << endl;
                return current;
            }
            else
            {
                cout << "Going through " << current->value << endl;
	
                     current = current->next;
            }
        } while(current);

	throw NotFoundError("Not found");
        //cout << "Not found: value " << value << endl;
	
        return nullptr;
    }
}

int main()
{
    List lista;




    
    auto node4 = make_shared<Node>(4);

   
    lista.add(node4);


   

  



    return 0;
}
0

To jest jakiś bezsens, elementy listy to prywatna sprawa listy, więc lista powinna wziąć za nie pełną odpowiedzialność, shared_ptr w tym kontekście zupełnie mija się ze zdrowym rozsądkiem.

0

Tutaj nie chodzi o zdrowy rozsądek, to nie jest moja lista dla moich potrzeb.
Pierwszy kod dostałem jako element zadania w ramach kursu, korzysta on z inteligentnych wskaźników tutaj shared_ptr dla listy złożonej z węzłów. Wszystko jest ok, valgrind stwierdza, ze zwalnia sie alokowana pamiec poprawnie.
Teraz mam za zadanie z tej "listy, która mija się z celem" przerobić na dwukierunkową listę wg tej konwencji wskaźników intel., przerobiłem i program sie nie wywala, jednak valgrind pokazuje wycieki pamieci. Pytanie jak to poprawić ?

2

Jeżeli ten kurs demonstruje użycie shared_ptr() dla elementów listy oraz/lub demonstruje dodawanie na koniec listy poprzez użycie pętli zamiast trzymania wskaźnika na ostatni element to rzuć ten kurs jak najprędzej bo niczego dobrego się z niego nie nauczysz.

0

Jest to kurs prowadzony przez jedną z wiodących firm IT w Polsce... Być może pokazanie shr_ptr na liście ma na celu jedynie zaprezentowanie ich działania w najprostszym przypadku (lista, node->next wskazuje na to samo co prev od next node'a), nie wiem po co szukać tutaj złośliwości... no chyba, że nie znasz odpowiedzi na moje pytanie, ale nie potrafisz zostawić tematu na forum bez odpowiedzi własnej ;) pozdrawiam

1 użytkowników online, w tym zalogowanych: 0, gości: 1