Я часто работаю с многомерными массивами, и я не являюсь большим поклонником std::vector
, так как это не возможно создать экземпляр std::vector
или std::vector
из std::vector
«s, используя ссылку без копирования базовых данных ,unique_ptr-х нулевого размера
Для одномерных массивов, я использую следующий
template<typename T>
using deleted_aligned_array = std::unique_ptr<T[], std::function<void(T*)> >;
template<typename T>
deleted_aligned_array<T> deleted_aligned_array_create(size_t n) {
return deleted_aligned_array<T>((T*)_mm_malloc(n*sizeof(T),16), [](T* f)->void { _mm_free(f);});
}
Это очень удобно и позволяет мне экземпляр динамически размеру массива, который также работает для нулевого размера. Кроме того, я могу использовать std::forward
для передачи данных без копирования.
Для двумерного массива, я хотел бы сделать что-то вроде
template<typename T>
using deleted_aligned_array2 = std::unique_ptr<T*,std::function<void(T**)>>;
template<typename T>
deleted_aligned_array2<T> deleted_aligned_array_create(size_t m, size_t n) {
auto arr = deleted_aligned_array2(new T*[m](), [&](T** x) {
if (malloc_usable_size(x) > 0) {
_mm_free(&(x[0][0]));
}
delete[] x;});
if (m*n > 0) {
arr.get()[0] = (T*) _mm_malloc(m*n*sizeof(T),16);
// Row pointers
for (size_t iRow = 1; iRow < m; iRow++) {
(m_data.get())[iRow] = &(m_data.get()[0][iRow*n]);
}
}
return arr;
}
Он работает для массивов нулевого размера, но я получаю сообщение об ошибке от valgrind
по понятным причинам, invalid read of size 8
.
Возможно ли это решить изящно, без создания целого класса, содержащего элемент std::unique_ptr
, где я реализую move-constructor, move-assign и т. Д. В конечном счете, я хотел бы обобщить это, чтобы использовать его для любых размер
template<typename T, size_t Dim>
deleted_aligned_array<T,D> deleted_aligned_array_create(...);
Возвращаемый массив должен быть уникальным указателем с указателем строки рекурсивно инициализирован и он должен поддерживать массивы нулевого размера, например,
auto arr = deleted_aligned_array_create<float,3>(4,5,10);
должен возвращать 3-мерный массив с указателями строк и столбцов.
Вопросы: 1) Избегайте чтения недействительных данных простым способом. 2) Используйте параметр шаблона D
для генерации типов: T*
, T**
и просто передайте D
, чтобы код рекурсивно генерировал указатели строк (это у меня уже есть). 3) Предпочтительно переносным способом. malloc_usable_size
является расширением GNU и называя его по x
приводит к недопустимому чтению, когда размер 0.
Заранее спасибо
* "STD :: вектор или зЬй :: вектор станд :: вектор, используя ссылку без копирования базовые данные "* Что вы имеете в виду? – Jarod42
Хорошим способом реализации многомерного массива является сглаживание массива и вычисление индекса вручную. – Jarod42
Если вы хотите использовать std :: vector в качестве типа аргумента для функции, вам необходимо создать экземпляр, и это вызовет копию. Я часто использую подмассивы многомерных массивов и хочу избежать копирования. –