@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;
}


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

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

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

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

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

Войти через центр авторизации
Похожие вопросы