2015-06-09 6 views
-2

У меня есть 1D-массив float64 arr[60], используемый для хранения значений напряжения из DAQ. Массив заполняется так:1D массив передан функции как 2D-массив

10 SAMPLES_PER_CHANNEL, 6 CHANNELS, grouped by channel 
transducer_0 transducer_1 ... transducer_6 
[0, 1 ..., 9, 10, 11 ..., 19 ... 50, 51 ..., 59] 

Я хотел бы хранить эти данные в 1D массив указателей и перейти к функции, определение которого является: bool func2(int samples, double* const* arr2)

[channel 0]     [channel 1]      [channel 5] 
{val 0, val 1 ...val 9}, {val 10, val 11 ...val 19}, ... 

Значения обновляются на ~ 5000 Гц и, как таковой, мне интересно, какие наиболее эффективные средства могут быть такими, чтобы я не копировал какие-либо данные.

Поскольку данные внутри arr хранятся в памяти одинаково для массива 1D или 2D, могу ли я просто нарисовать указатель?

+0

Не можете использовать этот вектор? Легче манипулировать ... Просто напишите структуру, такую ​​как 'struct Data {const char * channel; double val}; 'и добавьте это в вектор, и когда вам нужно просто вытащить нужные данные канала. – macroland

+1

Вы могли бы наложить указатель ... но было бы проще объявить 2D-массив ('float64 arr [6] [10]' вместо 'float64 arr [60]'), в первую очередь. – Dmitri

+1

Проблема заключается в том, что функция обратного вызова заполняет 1D-массив, и у меня нет доступа для изменения функции. –

ответ

1
template<size_t stride, class T, size_t N, size_t count = N/stride> 
std::array<T*, count> make_2d(T(&raw)[N]) { 
    std::array<T*, count> retval; 
    for (size_t i = 0; i < count; ++i) 
    retval[i] = raw + i*stride; 
    return retval; 
} 

это вернет array указателей на нижние размеры

Для вызова func2, просто сделать:

func2(10, make_2d<10>(arr).data()); 

это предполагает, что число образцов фиксируется, и что вы хотите массив указателей на каждый из выборок.

Вышеуказанное делает это без динамического распределения.

Отметьте, что arr должно быть типа double arr[60] для вышеуказанного, чтобы работать. float64, как мы надеемся, является псевдонимом double. Если arr является параметром функции, даже если он имеет номер 60, это не действительно double arr[60], но «действительно» double*.

Это может быть удосужился с немного творческого литья:

using parr_t = double(*)[60]; 
func2(10, make_2d<10>(*(parr_t)(arr)).data()); 

, если тот же массив (в том же месте в памяти) в настоящее время заселен с образцами неоднократно, вы можете сделать make_2d вызова один раз, и использовать его каждый раз.

+0

типографская строка 3 в размере шаблона. Должно быть, должно быть N? –

+0

@MattStokes yep. Исправлено и улучшено: вычисление 'count' теперь переносилось в аргументы' template'. – Yakk

+0

О том, хотел ли я получить доступ в обратном порядке - тот же порядок каналов, но с измененными значениями. Например. [channel0] {val 9, val 8, val 7 ...}? –

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