Как макет 2D области в памяти? Особенно, если это шахматная площадка. Учитывая, насколько я понимаю, эта память непрерывна, начиная от Max до 0, выделяет ли компьютер каждую область в этой области одну за другой? Если да, нужно ли изменить размер одной из областей в области, сдвигает ли она все остальные области вниз, чтобы освободить место для области нового размера?
Если необходимы уточнения:
C ++ 17/14/11
Лязг
Linux x86
Ревизия: (спасибо user4581301)
Я имею в виду vector<vector<T>>
, где T
- некоторый определенный тип. Я не говорю здесь о программировании шаблонов, если это ничего не меняет.
2 ответа
Точные детали реализации std::vector
будут варьироваться от компилятора к компилятору, но более чем вероятно, что std::vector
содержит член size_t
, который хранит длину и указатель на хранилище. Он выделяет это хранилище с использованием любого распределителя, указанного в шаблоне, но по умолчанию используется new
, который выделяет их из кучи. Вы, вероятно, знаете это, но обычно куча - это область ОЗУ под стеком в памяти, которая увеличивается снизу вверх по мере роста стека сверху вниз и которой среда выполнения управляет, отслеживая, какие ее блоки свободны.
Хранилище, управляемое std::vector
, представляет собой непрерывный массив объектов, поэтому вектор из двадцати векторов T
будет содержать как минимум size_t
, хранящий значение 20, и указатель на массив из двадцати структур, каждая из которых содержит длину и указатель. Каждый из этих указателей будет указывать на массив T
, непрерывно хранящийся в памяти.
Если вместо этого вы создадите прямоугольный двумерный массив, такой как T table[ROWS][COLUMNS]
или std::array< std::array<T, COLUMNS>, ROWS >
, вместо этого вы получите один непрерывный блок из T элементов, хранящихся в строчном порядке, то есть: все элементы строки 0, за которыми следуют все элементы строки 1, и так далее.
Если вы заранее знаете размеры матрицы, прямоугольный массив будет более эффективным, потому что вам нужно будет выделить только один блок памяти. Это быстрее, потому что вам нужно вызвать распределитель и деструктор только один раз, а не один раз для каждой строки, а также потому, что он будет в одном месте, а не разделен на множество разных мест, и, следовательно, один блок больше скорее всего будет в кеше процессора.
vector
- это тонкие оболочки вокруг динамически выделяемого массива своих элементов. Для vector<vector<T>>
это означает, что внешний внутренний массив vector
содержит внутренние структуры vector
, но внутренние vector
выделяют и управляют своими собственными внутренними массивами отдельно ( структура содержит указатель на управляемый массив).
По сути, 2D-аспект находится исключительно в логике программы; элементы любой заданной «строки» являются смежными, но между строками нет определенного пространственного отношения.
Истинные 2D-массивы (где базовая память выделяется как единый блок) на самом деле встречаются только с массивами в стиле C, объявленными с 2D-синтаксисом (int foo[10][20];
) и вложенными типами std::array
, или типами POD, следующими одним и тем же базовым дизайн.
Похожие вопросы
Новые вопросы
c++
C ++ - это язык программирования общего назначения. Первоначально он был разработан как расширение C и имеет аналогичный синтаксис, но теперь это совершенно другой язык. Используйте этот тег для вопросов о коде (который должен быть) скомпилирован с помощью компилятора C ++. Используйте тег для конкретной версии для вопросов, связанных с конкретной версией стандарта [C ++ 11], [C ++ 14], [C ++ 17], [C ++ 20] или [C ++ 23] и т. Д. .