LINUX.ORG.RU

C++ жадина или я дурак? (проблема с delete)

 , ,


0

4

Случилось страшное, убил весь день и вечер, не смог разобраться сам. Пересел с Си на Плюсы. Написал для своих задач реализацию листа (ниже полный листинг), все компилится и робит, но жрет память, точнее не отдает ее ОС после удаления узла из списка, судя по таск менеджеру, а только лишь после выхода. В чем может быть дело, друзья, что я делаю не так?:)

namespace Brevity {

    template <class T> class List {

    public:

        List();
        ~List();
        void add(T data);
        bool remove(size_t ind);
        bool swap(size_t src, size_t dst);
        size_t count();
        T *get(size_t ind);

    private:

        class Node {

        public:
            Node(T data);
            T data;
            Node *prev;
            Node *next;

        };

        Node *head;
        size_t length;
        Node *getNode(size_t ind);

    };

    template <class T> List<T>::Node::Node(T data) {
        this->data = data;
        this->prev = NULL;
        this->next = NULL;
    }

    template <class T> List<T>::List() {
        this->length = 0;
        head = NULL;
    }

    template <class T> List<T>::~List() {
        while (this->length > 0) {
            this->remove(0);
        }
    }

    template <class T> void List<T>::add(T data) {
        List::Node *newNode = new List::Node(data);
        if (this->length == 0) {
            newNode->prev = newNode;
            newNode->next = newNode;
            this->head = newNode;
        } else {
            newNode->prev = this->head->prev;
            newNode->next = this->head;
            this->head->prev->next = newNode;
            this->head->prev = newNode;
        }
        this->length++;
    }

    template <class T> bool List<T>::remove(size_t ind) {
        List::Node *curNode = List::getNode(ind);
        if (curNode == NULL) {
            return false;
        } else {
            if (ind == 0) {
                this->head = curNode->next;
            }
            if (this->length > 1) {
                curNode->prev->next = curNode->next;
                curNode->next->prev = curNode->prev;
            }
            delete curNode;
            this->length--;
            return true;
        }
    }

    template <class T> bool List<T>::swap(size_t src, size_t dst) {
        List::Node *srcNode, *dstNode;
        srcNode = List::getNode(src);
        dstNode = List::getNode(dst);
        if (srcNode == NULL || dstNode == NULL) {
            return false;
        } else {
            T tmp;
            tmp = srcNode->data;
            srcNode->data = dstNode->data;
            dstNode->data = tmp;
            return true;
        }
    }

    template <class T> typename List<T>::Node* List<T>::getNode(size_t ind) {
        if (this->length <= ind) {
            return NULL;
        } else {
            List::Node *curNode;
            size_t curInd;
            int increment;
            if (ind <= (size_t) (this->length / 2)) {
                curNode = this->head;
                curInd = 0;
                increment = 1;
            } else {
                curNode = this->head->prev;
                curInd = this->length - 1;
                increment = -1;
            }
            while (curInd != ind) {
                curNode = (increment > 0) ? curNode->next : curNode->prev;
                curInd += increment;
            }
            return curNode;
        }
    }

    template <class T> size_t List<T>::count() {
        size_t count = this->length;
        return count;
    }

    template <class T> T *List<T>::get(size_t ind) {
        return &List::getNode(ind)->data;
    }

}

int main(){

    Brevity::List <size_t > myList;
    for (size_t i = 0; i < 10000000; ++i) {
        myList.add(i);
    }

    for (size_t i = 0; i < 10000000; ++i) {
        myList.remove(0);
    }

    char a;
    std::cin >> a;

    for (int i = 0; i < myList.count(); ++i) {
        std::cout << *myList.get((size_t) i) << " ";
    }

}


Последнее исправление: zasyadko (всего исправлений: 2)
Ответ на: комментарий от invy

в примитивном бенчмарке вектор начинает довольно быстро сливать

Вот интереснее: https://baptiste-wicht.com/posts/2012/12/cpp-benchmark-vector-list-deque.html

Сначала сказал что Страуструп не прав, а ниже привел ссылку где почти на каждом графике list сливает вектору :)

pftBest ★★★★
()
Ответ на: комментарий от pftBest

Подозреваю что когда я мерял я сделал халтуру и померял вставку вначало :)

Не исключаю так же разницу в железе.

invy ★★★★★
()
Последнее исправление: invy (всего исправлений: 1)
Ответ на: комментарий от pftBest

Скомпилировал предоставленые по ссылке бенчмарки и прогнал у себя. Общее высказывание могу сделать такое: вектор начинает стабильно сливать если хранимые объекты больше 128 бит.

invy ★★★★★
()
Ответ на: комментарий от invy

Всё это зависит от такого числа параметров, что в отрыве от конкретной системы такие тесты вообще смысла не имеют. При этом связные списки почти никогда нормальный человек использовать не будет за отсутствием необходимости. Но очень редко надо, да. Или иногда не хочется писать громоздкий код на массиве.

dzidzitop ★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.