Размер std :: array, std :: vector и raw array - PullRequest
2 голосов
/ 08 января 2012

Позвольте нам иметь,

std::array <int,5> STDarr;
std::vector <int> VEC(5);
int RAWarr[5];

Я попытался получить их размер как,

std::cout << sizeof(STDarr) + sizeof(int) * STDarr.max_size() << std::endl;
std::cout << sizeof(VEC) + sizeof(int) * VEC.capacity() << std::endl;
std::cout << sizeof(RAWarr) << std::endl;

Выходные данные,

40
20
40

Являются ли эти вычисленияправильный?Учитывая, что у меня недостаточно памяти для std::vector и нет способа избежать динамического выделения, что мне следует использовать?Если бы я знал, что std::array приводит к снижению требований к памяти, я мог бы изменить программу, чтобы сделать массив статическим.

1 Ответ

4 голосов
/ 08 января 2012

Эти цифры неверны. Более того, я не думаю, что они представляют то, что вы думаете, они представляют, либо. Позвольте мне объяснить.

Сначала часть о том, что они ошибаются. Вы, к сожалению, не показываете значение sizeof(int), поэтому мы должны его получить. В системе, которую вы используете, размер int может быть вычислен как

size_t sizeof_int = sizeof(RAWarr) / 5; // => sizeof(int) == 8

потому что это, по сути, определение sizeof(T): это число байтов между началом двух соседних объектов типа T в массиве. Это несовместимо с номером печати для STDarr: в шаблоне класса std::array<T, n> указан массив n объектов типа T, встроенный в него. Более того, std::array<T, n>::max_size() - это константное выражение, дающее n. То есть имеем:

40                                               // is identical to
sizeof(STDarr) + sizeof(int) * STDarr.max_size() // is bigger or equal to
sizeof(RAWarr) + sizeof_int * 5                  // is identical to
40             + 40                              // is identical to
80

То есть 40 >= 80 - противопоказание.

Аналогично, второе вычисление также несовместимо с третьим вычислением: std::vector<int> содержит не менее 5 элементов, а capacity() должно быть больше, чем size(). Кроме того, размер std::vector<int> не равен нулю. То есть всегда должно быть верно следующее:

sizeof(RAWarr) < sizeof(VEC) + sizeof(int) * VEC.capacity()

В любом случае, все это в значительной степени не имеет отношения к тому, что кажется вам актуальным вопросом: каковы затраты на представление n объектов типа T с использованием встроенного массива T, std::array<T, n> и std::vector<T>? Ответ на этот вопрос:

  1. Встроенный массив T[n] использует sizeof(T) * n.
  2. std::array<T, n> использует тот же размер, что и T[n].
  3. A std::vector<T>(n) нуждается в некоторых управляющих данных (размер, емкость, и, возможно, и, возможно, распределитель) плюс как минимум 'n * sizeof (T)' байтов для представления его фактических данных. Он также может выбрать capacity() больше n.

В дополнение к этим числам для фактического использования любой из этих структур данных может потребоваться дополнительная память:

  1. Все объекты выровнены по соответствующему адресу. Для этого перед объектом может быть дополнительный байт.
  2. Когда объект размещается в куче, система управления памятью может включать пару байтов в дополнение к доступной памяти. Это может быть просто слово с размером, но это может быть любым механизмом распределения. Кроме того, эта память может жить где-то еще, чем память выделения, например где-то в хеш-таблице.

Хорошо, я надеюсь, что это дало некоторое представление. Тем не менее, здесь появляется важное сообщение: если std::vector<T> не может вместить объем данных, которые у вас есть, есть две ситуации:

  1. У вас очень мало памяти, и большая часть этого обсуждения бесполезна, потому что вам нужны совершенно разные подходы, чтобы справиться с теми немногими байтами, которые у вас есть. Это будет иметь место, если вы работаете со встроенными системами с чрезвычайно ограниченными ресурсами.
  2. У вас слишком много данных, и использование T[n] или std::array<T, n> не окажет особой помощи, поскольку обычно речь идет о не более 32 байтах.

Может быть, вы можете описать, что вы на самом деле пытаетесь сделать и почему std::vector<T> не вариант.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...