Ответ 1
Передача массивов в функции немного смешно в C и С++. Нет никаких значений типов массивов, поэтому вы фактически передаете указатель.
Чтобы адресовать 2D-массив (реальный, а не массив массивов), вам нужно передать 2 куска данных:
- указатель туда, где он запускается
- насколько широка одна строка
И это два отдельных значения, будь то C или С++ или с VLA или без или что-то еще.
Некоторые способы записать это:
Простейший, работает везде, но нуждается в более ручной работе.
void foo(int width, int* arr) {
arr[x + y*width] = 5;
}
VLA, стандарт C99
void foo(int width, int arr[][width]) {
arr[x][y] = 5;
}
VLA с реверсированными аргументами, объявление прямого параметра (расширение GNU C)
void foo(int width; int arr[][width], int width) {
arr[x][y]=5;
}
С++ w/VLA (расширение GNU С++, ужасно уродливое)
void foo(int width, int* ptr) {
typedef int arrtype[][width];
arrtype& arr = *reinterpret_cast<arrtype*>(ptr);
arr[x][y]=5;
}
Большое замечание:
Обозначение [x] [y] с 2D-массивом работает, потому что тип массива содержит ширину. Нет типов VLA = массивы должны быть исправлены во время компиляции.
Следовательно: если вы не можете использовать VLA, тогда...
- нет способа обработать его в C,
- Нет способа справиться с этим без прокси-класса с перегруженной операцией перегрузки в С++.
Если вы можете использовать расширения VLA (C99 или GNU С++), то...
- вы находитесь на зеленом в C,
- вам все еще нужен беспорядок на С++, вместо этого используйте классы.
Для С++ boost::multi_array
является прочным выбором.
Обходной путь
Для 2D-массивов вы можете сделать два отдельных выделения:
- 1D массив указателей на
T
(A) - 2D-массив
T
(B)
Затем установите указатели в (A) в соответствующие строки (B).
С помощью этой настройки вы можете просто передать (A) как простой T**
, и он будет хорошо вести себя с индексированием [x][y]
.
Это решение хорошо подходит для 2D, но для более высоких размеров требуется больше и больше шаблонов. Это также медленнее, чем решение VLA из-за дополнительного слоя косвенности.
Вы также можете запустить аналогичное решение с отдельным распределением для каждой строки B
. В C это выглядит как malloc-in-a-loop и аналогично векторам вектора С++. Однако это уберет преимущество наличия всего массива в одном блоке.