Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / C++ [игнор отключен] [закрыт для гостей] / Аллоцирование памяти в односвязном списке / 6 сообщений из 6, страница 1 из 1
15.11.2018, 23:26
    #39733831
Shevgeniy
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Аллоцирование памяти в односвязном списке
Допустим у нас есть класс, который реализует односвязный список (шаблонный класс).

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
template<typename T, class alloc = std::allocator<T>>
class try_list
{
    void push_back(T data)
    {
        if (head == nullptr)
        {
            head = new Node<T>(data);
        }
        else
        {
            Node<T> *current = this->head;

            while (current->pNext != nullptr)
            {
                current = current->pNext;
            }
//            T *_node = alloc(sizeof(T));
            current->pNext = new Node<T>(data);
        }
        Size++;
    }
    ...
private:
    template<typename U>
    class Node
    {
    public:
        Node *pNext;
        U data;
        Node(U data, Node *pNext = nullptr)
        {
            Node *_node = alloc(sizeof(Node)); // здесь компилятору законно не нравится то, что я аллокатор для инта пытаюсь применить для Node'ы

            this->data = data;
            this->pNext = pNext;
            *_node = this;
        }
    };
}



в прайват секции описана нода, которая состоит из данных и ссылки на следующий элемент.

Задача: с помощью своего аллокатора выделять память под элементы списка.
В чём вопрос:
Посмотрел List из библиотеки stl, там в шаблоне класса указано что аллокатор того же типа, что и данные, которые будет хранить List. Но мне же надо аллокатором выделять под всю ноду (или ноды) целиком, то есть аллокатор должен быть Alloc<Node>.
Не могу разобрать этой механики, под что должен выделять память аллокатор?
...
Рейтинг: 0 / 0
16.11.2018, 00:45
    #39733837
Anatoly Moskovsky
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Аллоцирование памяти в односвязном списке
Код: plaintext
1.
Node *_node = alloc(sizeof(Node)); 


alloc - это тип std::allocator<T> инстанцированный для типа T
Когда вы пишете Тип (...) то тут создается экземпляр типа Тип, т.е. в данном случае экземпляр std::allocator<T>. А потом вы его присваиваете в Node*, который вообще совершенно другого типа.
Т.е. тут вообще какая-то фигня написана.

Вместо этого вам надо получить тип std::allocator<Node<T>> и для него создать экземпляр и для него вызвать метод allocate()

Примерно так (пишу по памяти):
Код: plaintext
1.
2.
3.
alloc::rebind<Node<T>>::other alc; // rebind<B>::other дает тот же аллокатор для другого типа B
Node* node = alc.allocate(1);
alc.construct(node);



PS. В C++ 11 логика rebind реализуется также через std::allocator_traits
...
Рейтинг: 0 / 0
16.11.2018, 01:16
    #39733844
Shevgeniy
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Аллоцирование памяти в односвязном списке
То, что у меня фигня написана - факт.
Я примерно показал, что хотел бы реализовать.

Какой аллокатор и для какого типа я использовал в коде прекрасно знаю.

Вопрос в другом, как в контейнерах стандартной библиотеки это реализовано.

На счёт rebind - понял. Я забыл :) про его существование.
Спасибо большое.
...
Рейтинг: 0 / 0
18.11.2018, 22:36
    #39734865
Shevgeniy
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Аллоцирование памяти в односвязном списке
Anatoly Moskovsky, ещё раз спасибо.

Получилось вот так:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
template<typename T, class alloc = std::allocator<T>>
class try_list
{
public:
    try_list()
    {

        m_head = nullptr;
        m_size = 0;
    }

    void push_back(T data)
    {
        if (m_head == nullptr)
        {
            m_head = m_allocator.allocate(sizeof(Node<T>));
            *m_head = data;
        }
        else
        {
            Node<T> *current = this->m_head;
            while (current->pNext != nullptr)
            {
                current = current->pNext;
            }
            current->pNext = m_allocator.allocate(sizeof(Node<T>));
        }
        m_size++;
    }


private:

    template<typename U>
    class Node
    {
    public:
        Node *pNext;
        U data;

        Node(U data = U(), Node *pNext = nullptr)
        {
            this->data = data;
            this->pNext = pNext;
        }
    };
    int m_size;
    Node<T> *m_head;
    using node_alloc = typename alloc::template rebind<T>::other;
    node_alloc m_allocator;
};
...
Рейтинг: 0 / 0
18.11.2018, 23:03
    #39734874
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Аллоцирование памяти в односвязном списке
ShevgeniyПолучилось вот та

Разве параметр метода allocate() не количество создаваемых объектов?..
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
18.11.2018, 23:11
    #39734876
Shevgeniy
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Аллоцирование памяти в односвязном списке
Dimitry Sibiryakov, точно. Спасибо.
...
Рейтинг: 0 / 0
Форумы / C++ [игнор отключен] [закрыт для гостей] / Аллоцирование памяти в односвязном списке / 6 сообщений из 6, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]