Как макет 2D области в памяти? Особенно, если это шахматная площадка. Учитывая, насколько я понимаю, эта память непрерывна, начиная от Max до 0, выделяет ли компьютер каждую область в этой области одну за другой? Если да, нужно ли изменить размер одной из областей в области, сдвигает ли она все остальные области вниз, чтобы освободить место для области нового размера?

Если необходимы уточнения:

C ++ 17/14/11

Лязг

Linux x86

Ревизия: (спасибо user4581301)

Я имею в виду vector<vector<T>>, где T - некоторый определенный тип. Я не говорю здесь о программировании шаблонов, если это ничего не меняет.

1
Theko Lekena 14 Мар 2018 в 01:59

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, и так далее.

Если вы заранее знаете размеры матрицы, прямоугольный массив будет более эффективным, потому что вам нужно будет выделить только один блок памяти. Это быстрее, потому что вам нужно вызвать распределитель и деструктор только один раз, а не один раз для каждой строки, а также потому, что он будет в одном месте, а не разделен на множество разных мест, и, следовательно, один блок больше скорее всего будет в кеше процессора.

2
Davislor 13 Мар 2018 в 23:49

vector - это тонкие оболочки вокруг динамически выделяемого массива своих элементов. Для vector<vector<T>> это означает, что внешний внутренний массив vector содержит внутренние структуры vector, но внутренние vector выделяют и управляют своими собственными внутренними массивами отдельно ( структура содержит указатель на управляемый массив).

По сути, 2D-аспект находится исключительно в логике программы; элементы любой заданной «строки» являются смежными, но между строками нет определенного пространственного отношения.

Истинные 2D-массивы (где базовая память выделяется как единый блок) на самом деле встречаются только с массивами в стиле C, объявленными с 2D-синтаксисом (int foo[10][20];) и вложенными типами std::array, или типами POD, следующими одним и тем же базовым дизайн.

1
ShadowRanger 13 Мар 2018 в 23:22