Гарантируется ли линейное распределение под-массивов?
Я знаю, что этот ответ нарушает reinterpret_cast
правила, но это также предполагает, что под-массивы будут размещены линейно.
Я полагал, что это не гарантировано, но, когда я ищу стандарт, я чувствую, что моя уверенность колеблется. Если я статически выделю 2D-массив, как это:
int foo[][4] = { { 5, 7, 8 },
{ 6, 6 },
{},
{ 5, 6, 8, 9 } };
Могу ли я предположить, что все элементы будут расположены линейно? То есть если foo[0]
находится по адресу 0x00000042, будет:
foo[1]
быть по адресу 0x00000052foo[2]
быть по адресу 0x00000062foo[3]
быть по адресу 0x00000072
Эти адреса в шестнадцатеричном виде, и да, они предоставляют пространство для 4-элементного подмассива с sizeof(int) == 4
; они могут и не могут быть инициализированы нулями.
2 ответа
Гарантируется ли линейное распределение под-массивов?
Да. Независимо от того, являются ли элементы массива подмассивами или не массивными объектами, они гарантированно будут храниться в памяти непрерывно.
Для полноты вот стандартная цитата:
[Dcl.array]
- [snip] Объект массива содержит непрерывно размещенный непустой набор из N подобъектов типа T. [snip]
Нет исключения для случая, когда T
это массив.
Итак, мы знаем, что это не гарантируется
const char[4]
,
Напротив, мы знаем, что это гарантировано для char[4]
объекты так же, как это гарантировано для других типов.
Например: const char first[] = "foo"; char foo[][4] = {"bar", "foo", "", "baz"}
first
будет храниться в памяти как это:
{'f', 'o', 'o', '\0'}
foo
будет храниться так:
{'b', 'a', 'r', '\0', 'f', 'o', 'o', '\0', '\0', '\0', '\0', '\0', 'b', 'a', 'z', '\0'}
Так почему бы вам сказать, что это гарантировано для целых?
Это гарантировано для int[4]
, char[4]
и любой другой тип, который вы можете себе представить.
Из стандарта языка C ISO / IEC 9899 §6.2.5 Типы / p20 (Акцент на шахте):
Тип массива описывает непрерывно распределенный непустой набор объектов с конкретным типом объекта-члена, называемым типом элемента.
Также из стандарта языка C ISO / IEC 9899 §6.5.2.1 / p3 Массив подписки (выделение):
Последовательные операторы нижних индексов обозначают элемент объекта многомерного массива. Если
E
является n-мерным массивом (n >= 2) с размерамиi x j x . . . x k
, затемE
(используется как отличное от lvalue) преобразуется в указатель на(n - 1)
массив с размерамиj x . . . x k
, Если одинарный*
Оператор применяется к этому указателю явно или неявно в результате подписки, результатом является указатель на(n - 1)
-мерный массив, который сам конвертируется в указатель, если используется как lvalue. Из этого следует, что массивы хранятся в основном порядке строк (последний индекс изменяется быстрее всего).
Из вышеизложенного можно сделать вывод, что двумерный массив на самом деле является одномерным массивом, хранящимся в главном порядке строк.
Следовательно, можно предположить, что элементы подмассива хранятся в памяти непрерывно.