4

В моем коде я должен рассмотреть массив массивов, где внутренние массивы имеют фиксированный размер. Чтобы использовать алгоритмы STL, полезно фактически хранить данные в виде массива массивов, но мне также нужно передать эти данные в библиотеку C, которая принимает сглаженный массив C-стиля.C++ выравнивание структуры многомерного массива

Было бы здорово иметь возможность конвертировать (то есть сглаживать) многомерный массив дешево и переносимым образом. Я буду придерживаться очень простого случая, реальная проблема более общая.

struct my_inner_array { int data[3]; }; 
std::vector<my_inner_array> x(15); 

Является

&(x[0].data[0]) 

указатель на непрерывный блок памяти размером 45 * SizeOf (INT), содержащий те же элементы, что и х? Или мне нужно беспокоиться о выравнивании? Я боюсь, что это сработает для меня (по крайней мере, для определенных типов данных и размеров внутренних массивов), но это не переносимо.

  1. Этот код переносится?
  2. Если нет, есть ли способ заставить его работать?
  3. Если нет, есть ли у вас предложения, что я могу сделать?
  4. Это вообще ничего не меняет, если my_inner_array не является структурой POD, но содержит некоторые методы (до тех пор, пока класс не содержит никаких виртуальных методов)?
+0

Уместно ли использовать такой большой плоский массив в первую очередь и передать его, если это необходимо, [p, p + thide]? Стандартные алгоритмы позволяют абстрагироваться, действуют ли они на целый массив или его части. –

+0

@LucDanton: Например, я хотел бы применить функцию к массиву вершин. Я хотел бы использовать std :: transform (coord.begin(), coord.end(), values.begin(), f); где f является std :: function . Я не вижу другого способа применить std :: transform или другие алгоритмы STL напрямую. –

+0

'std :: transform (coord.begin(), coord.end(), values.begin(), adapt (f))' where' adapt (f) 'возвращает функтор, который извлекает начальную и конечную части (чтобы предположить, что он может быть записан для записи с парами итераторов, а не только с массивами). Или, может быть, вы можете написать общий «f», который может справиться с этим. Если вы используете что-то вроде Boost.Range, вам также не понадобится шаг «adapt». –

ответ

2

1 Теоретически нет. Компилятор может решить добавить дополнение к my_inner_array. На практике я не вижу причины, по которой компилятор добавит дополнение к структуре, в которой есть массив. В таком случае нет проблемы с выравниванием, создающей массив таких структур. Вы можете использовать время компиляции:

typedef int my_inner_array_array[3]; 
BOOST_STATIC_ASSERT(sizeof(my_inner_array) == sizeof(my_inner_array_array)); 

4 Если виртуальных методов нет, это не должно иметь никакого значения.

Смежные вопросы