@Acaunt

Как создать многомерный массив в одной области памяти?

Для класса мне нужен двумерный массив находящийся в одной области памяти. При этом я ещё собираюсь добавить конструктор перемещения и оператор перемещения, чтобы избежать множественного копирования данных.

На данный момент у меня только такой вариант:
Создать одномерный массив через динамическую память размером равным двумерному. И создать класс помощник для того чтобы мог обращаться к к элементам массива как к обычному двумерному массиву, с проверкой правильности индексов.

Вот небольшой пример:
Пример
#include <iostream>
#include <vector>

template<size_t Y, size_t X>
class MyClass {
private:
    class Indexing;
    
    std::vector<int> arr;
    
public:
    MyClass() : arr(Y * X, 0) {}
    
    MyClass(MyClass&& other) {
        arr = std::move(other.arr);
    }
    
    Indexing operator[](size_t index) {
        if (index > Y) {
            // бросаем исключение
        }
        
        return Indexing(&arr[index * X]);
    }
};

template<size_t Y, size_t X>
class MyClass<Y, X>::Indexing {
private:
    int* ptr;
    
public:
    Indexing(int* ptr) : ptr(ptr) {}
    
    int& operator[](size_t index) {
        if (index > X) {
            // бросаем исключение
        }
        
        return *(ptr + index);
    }
};
    
    

int main() {
    const size_t y = 3;
    const size_t x = 4;
    MyClass<y, x> a;
    
    for (size_t i = 0; i < y; ++i) {
        for (size_t j = 0; j < x; ++j) {
            std::cout << a[i][j] << " ";
        }
        std::cout << std::endl;
    }
    
    return 0;
}


Но кажется, что как то это костыльно. Видел ещё пример где создают два динамических массива где один массив указателей и этим указателям присваивают адреса на участки памяти из другого динамического массива.
  • Вопрос задан
  • 137 просмотров
Решения вопроса 2
AshBlade
@AshBlade
Просто хочу быть счастливым
Одномерный массив размером X * Y - единственное решение, если нужен непрерывный участок памяти.
Для получения первого индекса - index / X, для второго - index % X.
Но надо позаботиться - чтобы места было достаточно, иначе однажды получишь OOM либо когда место закончится, либо при сильной фрагментации памяти.

Вариант с "зубчатым" массивом, тоже норм - отложенное выделение можно реализовать. Но по скорости будет проигрывать из-за локальности данных. Хотя, если нужен непрерывный участок - уже не подходит
Ответ написан
wataru
@wataru Куратор тега C++
Разработчик на С++, экс-олимпиадник.
Есть еще 2 варианта:

1) Используйте std::vector<std::array>.

2) Что-то среднее между двумя вариантами у вас: как и везде, у вас есть одномерный массив для данных. А operator[] на классе возвращает int* на первый элемент в строке. То же, что у вас, только не надо никакого вспомогательного класса. Таким образом двойная индексация будет работать как надо. Но, как и во втором упомянутом вами примере, тут не будет проверки выхода за границы массива.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы