Динамический 2D-массив - это, по сути, массив указателей на массивы . Вы можете инициализировать его с помощью цикла, например:
int** a = new int*[rowCount];
for(int i = 0; i < rowCount; ++i)
a[i] = new int[colCount];
Вышеупомянутое для colCount = 5
и rowCount = 4
приведет к следующему:
Если Вы хотите 2-й массив целых чисел, какие элементы выделяются последовательно в памяти, необходимо объявить это как
int (*intPtr)[n] = new int[x][n]
, где вместо x можно записать любой размер, но n должен быть тем же в двух местах. Пример
int (*intPtr)[8] = new int[75][8];
intPtr[5][5] = 6;
cout<<intPtr[0][45]<<endl;
должен распечатать 6.
Попробуйте сделать это:
int **ary = new int[sizeY];
for (int i = 0; i < sizeY; i++)
ary[i] = new int[sizeX];
int** ary = new int[sizeY][sizeX]
должно быть:
int **ary = new int*[sizeY];
for(int i = 0; i < sizeY; ++i) {
ary[i] = new int[sizeX];
}
, а затем очистка будет:
for(int i = 0; i < sizeY; ++i) {
delete [] ary[i];
}
delete [] ary;
РЕДАКТИРОВАТЬ: , как указал Дитрих Эпп в комментариях, это не совсем легкое решение. Альтернативный подход заключается в использовании одного большого блока памяти:
int *ary = new int[sizeX*sizeY];
// ary[i][j] is then rewritten as
ary[i*sizeY+j]
typedef - ваш друг
Вернувшись назад и просмотрев многие другие ответы, я обнаружил, что нужно более глубокое объяснение, поскольку многие другие ответы либо страдают от проблем с производительностью, либо вынудить вас использовать необычный или обременительный синтаксис для объявления массива или доступа к элементам массива (или ко всему вышеперечисленному).
Во-первых, этот ответ предполагает, что вы знаете размеры массива во время компиляции. Если да, то это лучшее решение, поскольку оно даст наилучшую производительность и позволит вам использовать стандартный синтаксис массива для доступа к элементам массива .
Причина, по которой это дает лучшую производительность, заключается в том, что он выделяет все массивы как непрерывный блок памяти, что означает, что у вас, вероятно, будет меньше пропусков страниц и лучшая пространственная локальность. Выделение в цикле может привести к тому, что отдельные массивы окажутся разбросанными по нескольким несмежным страницам в пространстве виртуальной памяти, поскольку цикл выделения может быть прерван (возможно, несколько раз) другими потоками или процессами, или просто по усмотрению распределитель заполняет небольшие пустые блоки памяти, которые у него есть.
Другими преимуществами являются простой синтаксис объявления и стандартный синтаксис доступа к массиву.
В C ++ с использованием new:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv) {
typedef double (array5k_t)[5000];
array5k_t *array5k = new array5k_t[5000];
array5k[4999][4999] = 10;
printf("array5k[4999][4999] == %f\n", array5k[4999][4999]);
return 0;
}
или в стиле C с использованием calloc:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv) {
typedef double (*array5k_t)[5000];
array5k_t array5k = calloc(5000, sizeof(double)*5000);
array5k[4999][4999] = 10;
printf("array5k[4999][4999] == %f\n", array5k[4999][4999]);
return 0;
}
Я предполагаю из вашего примера статического массива, что вам нужен прямоугольный массив, а не зубчатый. Вы можете использовать следующее:
int *ary = new int[sizeX * sizeY];
Затем вы можете получить доступ к элементам как:
ary[y*sizeX + x]
Не забудьте использовать delete [] для или
.
Этот вопрос меня беспокоил - это достаточно распространенная проблема, и хорошее решение уже должно существовать, что-то лучше, чем вектор векторов или вращение вашей собственной индексации массива.
Когда что-то должно быть существует в C ++, но не существует, в первую очередь следует поискать boost.org . Там я нашел Boost Multidimensional Array Library, multi_array
. Он даже включает класс multi_array_ref
, который можно использовать для обертывания вашего собственного одномерного буфера массива.