Как выделить 2D массив указателей в C++

Для создания цвета попробуйте это:

Device device = Display.getCurrent ();
Color red = new Color (device, 255, 0, 0);
12
задан Peter Mortensen 17 November 2010 в 16:10
поделиться

9 ответов

По букве закона, вот как это сделать:

// Create 2D array of pointers:
int*** array2d = new (int**)[rows];
for (int i = 0; i < rows; ++i) {
  array2d[i] = new (int*)[cols];
}

// Null out the pointers contained in the array:
for (int i = 0; i < rows; ++i) {
  for (int j = 0; j < cols; ++j) {
    array2d[i][j] = NULL;
  }
}

Будьте осторожны, чтобы удалить содержащиеся указатели, массивы строк и массив столбцов по отдельности и в правильном порядке.

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

22
ответ дан 2 December 2019 в 03:43
поделиться

Это зависит от обстоятельств. Это может быть очень просто:

int main()
{
    int*   data1[10][20]; // Fixed size known at compile time

    data1[2][3] = new int(4);
}

Если вам нужны динамические размеры во время выполнения, вам нужно проделать некоторую работу.
Но Boost поможет вам:

int main()
{
   int  x;
   int  y;
   getWidthAndHeight(x,y);

   // declare a 2D array of int*
   boost::multi_array<int*,2>   data1(boost::extents[x][y]);

   data[2][3] = new int(6);
}

Если вас устраивают зубчатые массивы , которые могут расти динамически:

int main()
{
    std::vector<std::vector<int*> >   data1;

    data1.push_back(std::vector<int*>(10,NULL));
    data1[0][3] = new int(7);
}

Примечание: Во всем вышеперечисленном. Я предполагаю, что массив не владеет указателем. Таким образом, он не выполнял никакого управления указателями, которые он содержит (хотя для краткости я использовал new int () в примерах). Чтобы правильно управлять памятью, вам нужно еще немного поработать.

5
ответ дан 2 December 2019 в 03:43
поделиться
int *pointerArray[X][Y];
int **ptrToPointerArray = pointerArray;

Вот как вы делаете true (непрерывный в памяти) многомерный массив.

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

int *pointerArray[8][6]; // declare array of pointers
int **ptrToPointerArray = &pointerArray[0][0]; // make a pointer to the array
int *foo = pointerArray[3][1]; // access one element in the array
int *bar = *(ptrToPointerArray + 3*8 + 1); // manually perform row-major indexing for 2d array

foo == bar; // true
int *baz = ptrToPointerArray[3][1]; // syntax error
4
ответ дан 2 December 2019 в 03:43
поделиться
double** array = new double*[rowCnt];
for (int row = 0; row < rowCnt; ++row)
  array[row] = new double[colCnt];
for (int row = 0; row < rowCnt; ++row)
  for (int col = 0; col < colCnt; ++col)
    array[row][col] = 0;
3
ответ дан 2 December 2019 в 03:43
поделиться

Вы можете попробовать Boost :: MultiArray.

Подробности см. На этой странице .

3
ответ дан 2 December 2019 в 03:43
поделиться

:)

Однажды они были у меня в коде, который я написал.

Я был посмешищем команды, когда просочились первые ошибки. Вдобавок мы используем венгерскую нотацию, что приводит к имени типа papChannel - указатель на массив указателей ...

Это нехорошо. Лучше использовать typedef для определения «строки столбцов» или наоборот. Также делает индексацию более понятной.

typedef int Cell;
typedef Cell Row[30];
typedef Row Table[20];

Table * pTable = new Table;

for( Row* pRow = *pTable; pRow != *pTable+_countof(*pTable); ++pRow ) {
   for( Cell* pCell = *pRow; pCell != *pRow + _countof(*pRow); ++pCell ) {
     ... do something with cells.
   }
}
1
ответ дан 2 December 2019 в 03:43
поделиться

Я предпочитаю использовать оператор (). Для этого есть множество причин (ответы на часто задаваемые вопросы по C ++ 13.10 ). Измените внутреннее представление на std :: vector , если хотите:

template <class T, int WIDTH, int HIEGHT>
class Array2d
{
public:
    const T& operator ()(size_t col, size_t row) const
    {
        // Assert col < WIDTH and row < HIEGHT
        return m_data [( row * WIDTH + col)];
    }
    T& operator ()(size_t col, size_t row)
    {
        // Assert col < WIDTH and row < HIEGHT
        return m_data [( row * WIDTH + col)];
    }
private:
T m_data[WIDTH * HIEGHT];
};

Вы можете использовать его так:

Array2d< Object*, 10, 10 > myObjectArray;
myObjectArray(5,6) = new Object();
1
ответ дан 2 December 2019 в 03:43
поделиться

Вы можете определить вектор векторов:

typedef my_type *my_pointer;

typedef vector<vector<my_pointer> > my_pointer2D;

Затем создать класс, производный от my_pointer2D, например:

class PointersField: public my_pointer2D
{
  PointsField(int n, int m)
  {
     // Resize vectors....
  }
}

PointsField pf(10,10); // Will create a 10x10 matrix of my_pointer
1
ответ дан 2 December 2019 в 03:43
поделиться

См. Мой код. Он работает в моей системе FC9 x86_64:

#include <stdio.h>

template<typename t>
struct array_2d {
        struct array_1d {
                t *array;
                array_1d(void) { array = 0; }
                ~array_1d()
                {
                    if (array) {
                         delete[] array;
                         array = 0;
                    }
                }
                t &operator[](size_t index) { return array[index]; }
        } *array;
        array_2d(void) { array = 0; }
        array_2d(array_2d<t> *a) { array = a->array; a->array = 0; }
        void init(size_t a, size_t b)
        {
                array = new array_1d[a];
                for (size_t i = 0; i < a; i++) {
                        array[i].array = new t[b];
                }
        }
        ~array_2d()
        {
                if (array) {
                        delete[] array;
                        array = 0;
                }
        }
        array_1d &operator[](size_t index) { return array[index]; }
};

int main(int argc, char **argv)
{
        array_2d<int> arr = new array_2d<int>;
        arr.init(16, 8);

        arr[8][2] = 18;
        printf("%d\n",
                arr[8][2]
                );

        return 0;
}

Effo UPD: ответ на вопрос «Разве это не массив указателей на массивы?», Добавляющий пример массива указателей, очень просто:

int main(int argc, char **argv)
{
        array_2d<int*> parr = new array_2d<int*>;
        int i = 10;
        parr.init(16, 8);
        parr[10][5] = &i;
        printf("%p %d\n",
                parr[10][5],
                parr[10][5][0]
                );

        return 0;
}

Я все еще неправильно понял ваш вопрос?

И вы могли бы даже

typedef array_2d<int*> cell_type;
typedef array_2d<cell_type*> array_type;

int main(int argc, char **argv)
{
    array_type parr = new array_type;
    parr.init(16, 8);
    parr[10][5] = new cell_type;
    cell_type *cell = parr[10][5];
    cell->init(8, 16);
    int i = 10;
    (*cell)[2][2] = &i;

    printf("%p %d\n",
            (*cell)[2][2],
            (*cell)[2][2][0]
            );

    delete cell;

    return 0;
}

Это также работает в моей системе FC9 x86_64.

0
ответ дан 2 December 2019 в 03:43
поделиться
Другие вопросы по тегам:

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