С Новым годом! Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.67/15: Рейтинг темы: голосов - 15, средняя оценка - 4.67
0 / 0 / 0
Регистрация: 26.09.2014
Сообщений: 17
1

А что под капотом у vector?

25.07.2018, 18:32. Показов 3012. Ответов 13
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Не знаю куда написать и вроде тем отвечающий на вопрос не нашел.

Вопрос заключается в том, что мне прекрасно известно, что такое шаблоны функций и классов, и какие минусы они имеют, в том числе что реализацию, должна быть в том же файле. Интересно, а как решена эта проблема в стандартных контейнерах, на примере vector. Мне кажется он как-то сохраняет внутри своего состояние тип данных. Может не прав, мне для лучшего понимания, как устроен язык.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
25.07.2018, 18:32
Ответы с готовыми решениями:

Под капотом вызова функции
Решил разобраться как вызываются функции в c++. То есть как компилятор преобразовывает код в...

Что под капотом std::mutex
Собственно сабж. Под виндой это сделано на основе критической секции или через мьютекс как объект...

Нюансы синтаксиса: что означает запись vector<int*> a и vector <int>*a ?
Часто встречается вот такая запись: vector&lt;int&gt; a; это понятно что. Массив объектов int А вот...

Перегрузка операторов под vector
Добрый день. Просьба направить в правильном направлении при перегрузке операторов : ...

13
1468 / 1009 / 456
Регистрация: 30.10.2017
Сообщений: 2,800
25.07.2018, 18:35 2
Лучший ответ Сообщение было отмечено sed99 как решение

Решение

Цитата Сообщение от sed99 Посмотреть сообщение
в том числе что реализацию, должна быть в том же файле
Необязательно. Реализация может быть и в заголовочном файле.
1
зомбяк
1584 / 1218 / 345
Регистрация: 14.05.2017
Сообщений: 3,940
25.07.2018, 18:43 3
Цитата Сообщение от sed99 Посмотреть сообщение
в том числе что реализацию, должна быть в том же файле. Интересно, а как решена эта проблема в стандартных контейнерах, на примере vector
Если IDE поддерживает пошаговую отладку внутри стандартной библиотеки, то вполне сможешь убедиться, что в ней реализация стандартных контейнеров как раз и находится в заголовочных файлах.
Прятать реализацию полностью в cpp-файлы можно только в том случае, если "снаружи" (в заголовочных файлах, передаваемых для компиляции) не используются никакие внутренние шаблоны.
0
Комп_Оратор)
Эксперт по математике/физике
8977 / 4704 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
25.07.2018, 18:56 4
Лучший ответ Сообщение было отмечено sed99 как решение

Решение

sed99,
Цитата Сообщение от sed99 Посмотреть сообщение
Мне кажется он как-то сохраняет внутри своего состояние тип данных.
Тип это не состояние. Это богатство. Причём времени компиляции. Там внутри масссив обычно. Начиная с С++/11 он доступен. По умолчанию аллокатор - allocator<T>. Память выделяется в куче, то есть. А раздельная компоновка шаблонов не случилась.
1
2784 / 1937 / 570
Регистрация: 05.06.2014
Сообщений: 5,602
25.07.2018, 19:29 5
Цитата Сообщение от sed99 Посмотреть сообщение
Интересно, а как решена эта проблема в стандартных контейнерах, на примере vector.
Никак. И вообще, там есть куда более серьезная проблема - алгоритм расширения массива методом "создать новый массив побольше и скопировать в него старый". HEAP_REALLOC_IN_PLACE_ONLY? Не, не слышали (мало ли что аналоги не в любом менеджере памяти есть, это не повод вообще игнорировать существование подобных функций).
Цитата Сообщение от sed99 Посмотреть сообщение
в том числе что реализацию, должна быть в том же файле.
У std::map значительную часть кода (ребалансировка красно-черного дерева) вполне можно вынести из шаблона и запихать в cpp.
0
4264 / 3323 / 925
Регистрация: 25.03.2012
Сообщений: 12,520
Записей в блоге: 1
25.07.2018, 20:32 6
Renji, и в чём тут проблема? Ничего, что это известная фича С++ как языка, которую учитывают при написании программ? (специально, например не сорханяя указателей, ссылок и итераторов на элементы на постоянной основе)
В чём вообще выгода от использования HEAP_REALLOC_IN_PLACE_ONLY? Использовать в каких-то программах, которые не приемлют копирование данных вообще?
Но если она сфейлит, придётся всё равно расширяться копированием массива пусть потом, но рано или поздно, а значит и она не подойдёт для этой задачи.
Или будет такая программа в зависимости от наличия heapa либо продолжать работу либо вообще завершаться типа "ну извините, мы завели кучу указателей, ссылок и итераторов на элементы вектора и теперь не можем его расширить, попробуйте перезагрузить компьютер"
0
2784 / 1937 / 570
Регистрация: 05.06.2014
Сообщений: 5,602
25.07.2018, 20:57 7
Цитата Сообщение от Kuzia domovenok Посмотреть сообщение
В чём вообще выгода от использования HEAP_REALLOC_IN_PLACE_ONLY? Использовать в каких-то программах, которые не приемлют копирование данных вообще?
Выгода в константной сложности такой реаллокации (менеджер памяти просто меняет запись "размер блока"). Но, разумеется, в случае если in place провалилось, нам придется откатиться на классический алгоритм, с классической же линейной сложностью.

Плюс, мы снижаем требования к памяти. Представьте что массив занимает сто мегабайт, а свободно только пятьдесят. In place реаллокация вполне может сработать даже в таких условиях. А вот классическое "создать новый массив" гарантированно провалится.
0
0 / 0 / 0
Регистрация: 26.09.2014
Сообщений: 17
26.07.2018, 10:44  [ТС] 8
Цитата Сообщение от Renji Посмотреть сообщение
Никак. И вообще, там есть куда более серьезная проблема - алгоритм расширения массива методом "создать новый массив побольше и скопировать в него старый". HEAP_REALLOC_IN_PLACE_ONLY? Не, не слышали (мало ли что аналоги не в любом менеджере памяти есть, это не повод вообще игнорировать существование подобных функций).
Нет. Не слышал. Спасибо, что открыл такую истину простую.

-----------------------------------------------------------------------------
Цитата Сообщение от IGPIGP Посмотреть сообщение
Тип это не состояние. Это богатство. Причём времени компиляции. Там внутри масссив обычно. Начиная с С++/11 он доступен. По умолчанию аллокатор - allocator<T>. Память выделяется в куче, то есть. А раздельная компоновка шаблонов не случилась.
Это работает так, сначала мы выделяем кучу, потом в этой куче мы работает из нашей структуры данных, используя шаблоны, при этом раздельной компоновки шаблона не будет? У меня правильное понимание процесса?
0
зомбяк
1584 / 1218 / 345
Регистрация: 14.05.2017
Сообщений: 3,940
26.07.2018, 10:59 9
Цитата Сообщение от sed99 Посмотреть сообщение
У меня правильное понимание процесса?
Неправильное. Вначале в шаблон подставляются/подбираются параметры, с которыми он должен быть скомпилирован, потом он вместе со всеми прочими функциями компилируется, и во время выполнения, если речь идёт о стандартных контейнерах, часто состоит из двух частей - одна часть в стеке и с её помощью мы управляем содержимым контейнера, и есть вторая, в куче, в которой содержатся данные, которыми управляет контейнер.

Раздельной компоновки шаблона не может быть из-за того, что до тех пор, пока не известны параметры (т.е. типы данных) с которыми он будет работать, скомпилировать(т.е. преобразовать в машинный код) шаблон невозможно.
0
Комп_Оратор)
Эксперт по математике/физике
8977 / 4704 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
26.07.2018, 14:18 10
Цитата Сообщение от sed99 Посмотреть сообщение
Это работает так, сначала мы выделяем кучу, потом в этой куче мы работает из нашей структуры данных, используя шаблоны, при этом раздельной компоновки шаблона не будет? У меня правильное понимание процесса?
Нет. Буквально ничего понимать не нужно.
По умолчанию вектор выделяет память в куче. Кучу выделять не нужно, - тут вообще нечего бояться. Как уже сказали есть такой момент когда выделенной памяти недостаточно и производится реалокейт.
Что касается состояния связанного с типом, то нет состояния. Состояние это действительно набор данных, которые можно созранить, изменить... Тип задаётся на этапе компиляции. И на этом же этапе выводится тип вектора - инстанциируется шаблон. То есть vector<int> и vector<double> это разные типы (разные инстансы одного шаблона vector<typename T> ). Именно понимание того, что шаблон класса это верно, но редко используется, а шаблонный класс, это неверно и поэтому используется на каждом шагу, может помочь различить задачу компилятора работающего с типом и его же задачу при работе с шаблоном типа. Когда линкер видит объявление он ищет реализацию для связывания вызывающего кода и вызываемого кода. Это собственно уже объектные файлы на тот момент. Но если мы имеем дело с инстанциированием, то код типа ещё нужно сгенерировать, а потом связывать. Поэтому, не удался замысел, касающийся таинственного слова export :
(тут была ссылка на stackoverflow которую сервер удалил). Прогуглите ключевое слово export C++ и вы её увидите.
Это касается не столь контейнеров, сколь шаблонов как таковых. Почему никто из разработчиков компиляторов не нашёл удовлетворительного способа поддерживать данную возможность я написал. Но повторять, это механически как детскую считалку не имеет смысла.
1
0 / 0 / 0
Регистрация: 26.09.2014
Сообщений: 17
26.07.2018, 14:29  [ТС] 11
Цитата Сообщение от TRam_ Посмотреть сообщение
Неправильное. Вначале в шаблон подставляются/подбираются параметры, с которыми он должен быть скомпилирован, потом он вместе со всеми прочими функциями компилируется, и во время выполнения, если речь идёт о стандартных контейнерах, часто состоит из двух частей - одна часть в стеке и с её помощью мы управляем содержимым контейнера, и есть вторая, в куче, в которой содержатся данные, которыми управляет контейнер.

Так, на момент компиляции заместо шаблона класса, мы получаем для данного типа данных свой вид класса, (вопрос, если два раза использовать тип данных int, будет создан два вида класса для int'а или нет?)?
И про две части, можно чуть более раскрыто. Первый это просто интерфейс - vector, второй работает не посредственно с кучей - это allocator?

Понимаю, что для многих это очевидная вещь, но мне до этого с таким не приходилось сталкиваться, и это момент важен для дальнейшего понимания.
0
Комп_Оратор)
Эксперт по математике/физике
8977 / 4704 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
26.07.2018, 14:42 12
Цитата Сообщение от sed99 Посмотреть сообщение
если два раза использовать тип данных int, будет создан два вида класса для int'а или нет?
sed99, контейнер stl это вид шаблона. Вы изучаете вид шаблона не имея начального представления о том, что из себя представляет шаблон. Это бессмыслесное занятие.
Цитата Сообщение от sed99 Посмотреть сообщение
если два раза использовать тип данных int, будет создан два вида класса для int'а или нет?
не будет. Класс один и тот же. Используя typedef или using можно объявить синоним типа и использовать только его для объевления объектов.
0
зомбяк
1584 / 1218 / 345
Регистрация: 14.05.2017
Сообщений: 3,940
26.07.2018, 15:14 13
Лучший ответ Сообщение было отмечено sed99 как решение

Решение

Цитата Сообщение от sed99 Посмотреть сообщение
(вопрос, если два раза использовать тип данных int, будет создан два вида класса для int'а или нет?)
Один и тот же шаблон с одним и тем же набором параметров (например std::vector<int>) рассматривается как один и тот же класс.

Цитата Сообщение от sed99 Посмотреть сообщение
Первый это просто интерфейс - vector, второй работает не посредственно с кучей - это allocator?
Лучше сказать так "объект vector использует инструмент allocator для выполнения нужных действий над кучей". Но ранее написал не об этом, а о том, что в результате в памяти vector хранится в двух местах - в стеке как локальная/глобальная переменная (с полями, содержащими размер, размер выделенной в куче памяти, адрес данных в куче) и в куче, как некий динамически выделенный массив с данными.
При командах, не связанных с пересозданием места в куче vector использует свои собственные алгоритмы работы с данными и указатель на них, а если пересоздание места требуется, то используются как свои, так и алгоритмы allocator'а, заданного в качестве одного из параметров шаблона у vector'а (если этот параметр не указан, используется аллокатор по-умолчанию).
1
0 / 0 / 0
Регистрация: 26.09.2014
Сообщений: 17
26.07.2018, 17:26  [ТС] 14
Цитата Сообщение от TRam_ Посмотреть сообщение
Лучше сказать так "объект vector использует инструмент allocator для выполнения нужных действий над кучей". Но ранее написал не об этом, а о том, что в результате в памяти vector хранится в двух местах - в стеке как локальная/глобальная переменная (с полями, содержащими размер, размер выделенной в куче памяти, адрес данных в куче) и в куче, как некий динамически выделенный массив с данными.
При командах, не связанных с пересозданием места в куче vector использует свои собственные алгоритмы работы с данными и указатель на них, а если пересоздание места требуется, то используются как свои, так и алгоритмы allocator'а, заданного в качестве одного из параметров шаблона у vector'а (если этот параметр не указан, используется аллокатор по-умолчанию).
Спасибо, теперь стало понятно, как это все устроено и что дальше смотреть)
0
26.07.2018, 17:26
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
26.07.2018, 17:26
Помогаю со студенческими работами здесь

Выделение памяти под vector, размером 2^1000
Доброго всем дня. у меня есть задача задач. найти число которое есть 2^1000. оно, увы выходит за...

Отличие выделения адресатов памяти под vector
Почему при исполнении программы первая ячейка отличается от следующих. И почему не заполняются...

error LNK2019: ссылка на неразрешенный внешний символ "public: __thiscall Vector<int>::Vector<int>(void)" (?0?$Vector@H@@QAE@XZ) в функции _main
//Vector.h #include &lt;iostream&gt; #include &lt;Windows.h&gt; #include &lt;climits&gt; #include &lt;vector&gt;...

Как можно увеличить размер вектора, который является элементом вектора vector<vector<int>>arr(n, vector <int>)
Написал программу, которая создает вектор 'а' векторов 'b', вектора 'b' содержат 2 числа. Стало...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
14
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru