Гарантируется ли линейное распределение под-массивов?

Я знаю, что этот ответ нарушает reinterpret_cast правила, но это также предполагает, что под-массивы будут размещены линейно.

Я полагал, что это не гарантировано, но, когда я ищу стандарт, я чувствую, что моя уверенность колеблется. Если я статически выделю 2D-массив, как это:

int foo[][4] = { { 5, 7, 8 },
                 { 6, 6 },
                 {},
                 { 5, 6, 8, 9 } };

Могу ли я предположить, что все элементы будут расположены линейно? То есть если foo[0] находится по адресу 0x00000042, будет:

  • foo[1] быть по адресу 0x00000052
  • foo[2] быть по адресу 0x00000062
  • foo[3] быть по адресу 0x00000072

Эти адреса в шестнадцатеричном виде, и да, они предоставляют пространство для 4-элементного подмассива с sizeof(int) == 4 ; они могут и не могут быть инициализированы нулями.

2 ответа

Решение

Гарантируется ли линейное распределение под-массивов?

Да. Независимо от того, являются ли элементы массива подмассивами или не массивными объектами, они гарантированно будут храниться в памяти непрерывно.

Для полноты вот стандартная цитата:

[Dcl.array]

  1. [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. Из этого следует, что массивы хранятся в основном порядке строк (последний индекс изменяется быстрее всего).

Из вышеизложенного можно сделать вывод, что двумерный массив на самом деле является одномерным массивом, хранящимся в главном порядке строк.

Следовательно, можно предположить, что элементы подмассива хранятся в памяти непрерывно.

Другие вопросы по тегам