2013-12-01 4 views
1

Я столкнулся с проблемой - я не могу объявить 2D-массивы в C++, используя целые числа, написанные пользователем.Невозможно объявить динамический 2D-массив в C++

Этот код работает мелко-

cin>>m>>n; 
int *array; 
array=new int[m*n]; 

Но я не могу сделать эту работу -

cin>>m>>n; 
int *array; 
array=new int[m][n]; 

Любые идеи, как я могу обойти это? P.S. ошибка: не может преобразовать 'int () [2]' to 'int' в задании.

+0

Вы не пытаетесь * объявить * динамический массив (который на самом деле незаконным в C++, все массивы должны быть фиксированного размера). Вы пытаетесь * выделить * динамический массив. – john

ответ

2

Изменить

cin>>m>>n; 
int *array; 
array=new int[m][n]; 

в

cin>>m>>n; 
int **array; 
array=new int * [m]; 

for (int i = 0; i < m; i++) array[i] = new int[n]; 
+0

Спасибо, это сработало для меня. – Nick

+0

Не забудьте удалить все выделенные указатели. –

+3

Не забывайте _explain_ свой ответ, а не вредный демпинг-код для тех, кто этого не понимает. –

0

Во-первых, я предлагаю вам использовать std :: vector, чтобы избежать проблем с распределением памяти/освобождением памяти.

Если вам нужна реализация массива, вы можете объявить массив как указатель на указатель на int.

cin>>m>>n; 
int **array = new *int[m]; 
for (int I = 0; I < m; I++) { 
    array[I] = new int[n]; 
} 
+0

Спасибо, не знали про векторы. – Nick

0

array является int * и вы пытаетесь присвоить int ** ... изменить массив int**.

2D массив - это массив массивов, поэтому вам нужен указатель на указатель.

+0

Ну, массивы не указатели, они только * разлагаются * указателями при использовании. Таким образом, массив, объявленный как 'int array [m] [n]', является * not * указателем на указатель, но является одной последовательной плитой из m массивов длины n. Нет никакого массива указателей. – cmaster

+0

@cmaster array не является указателем, но переменная 'array' в вопросе очень указательна. Пожалуйста, прочитайте еще раз, я просто сказал, что ему ** нужен ** указатель на указатель! – MeNa

+1

Нет, у вас не может быть указателя на указатель, указывающий на массивы массивов. Ни типы, ни макеты элементов не совместимы. –

0

Это потому, что вы можете использовать только new для распределения 1D массивов. На самом деле, 2D-массивы также являются 1D-массивами, где в большинстве систем все строки просто конкатенируются. Это называется макетом памяти строки.

Вы можете эмулировать 2D-массивы с массивом 1D. Конверсия индекс:

index1 = y * m + x

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

+0

«Вы можете использовать только новые, чтобы выделить 1D-массивы» неверно, вы можете выделять массивы любого типа, включая массивы массивов, которые являются не чем иным, как многомерными массивами. Взгляните на мой ответ, если вы мне не верите. – cmaster

0

Вы можете сделать это:

typedef int RowType[n]; 
RowType *array = new RowType[m]; 

doStuffWith(array[y][x]); 

Или еще короче (но труднее запомнить):

int (*array)[n] = new (int[m][n]); 

Edit:

Существует поймать в C++, что размеры массива должны быть постоянными для оператора new, так что вы можете сделать это, только если n является const.Это не является проблемой в C (и почему я забыл об этом), поэтому следующие работы, даже если п и т не Const:

RowType *array = (RowType*)malloc(m * sizeof(RowType)); 

Конечно, вы можете обойти это ограничение в C++, выполнив это, который работает, даже если оба m и n динамичны:

RowType *array = (RowType*)new int[m * n]; 

typedef бесплатная версия будет это:

int (*array)[n] = (int (*)[n])new int[m *n]; 
+0

Нет, вы не можете;) Если что-нибудь, то n должно быть постоянным, я верю, что это не случай. –

+0

Чтобы быть в состоянии сделать это так, n должно быть постоянным, и это не так. –

+0

@Bartek Вы правы, в C++ есть улов. Не хорошо. C не имеет таких * интересных * ограничений ... – cmaster

0

Подобно тому, как дом я сказал (но неindex1=y*m+x а index1=x*n+y эмулировать нужную запись):

int *array = new int [m*n]; 

int get (int x, int y) // emulates array[x][y] for array[m][n] 
{ 
    return array[x*n+y]; 
} 

Однако, я думаю, что реальное 2-мерное распределение (как Влад из Москвы показал вам) медленнее в создании (и потребности немного больше памяти), но быстрее в доступе. Причина array[x*n+y] == *(array+x*n+y), wether array[x][y] == *(*(array+x)+y), поэтому у вас есть одно умножение меньше, но одно разделение больше, в сумме Я думаю, это быстрее.

Вы также можете создать класс:

class array2d 
{ 
private: 
    int *data; 
    int mm, nn; 
public: 
    array2d (int m, int n) 
    { 
     mm = m; 
     nn = n; 
     data = new int [m*n];  
    } 
    ~array2d() 
    { 
     delete[] data; 
    } 
    int *operator[] (int x) 
    { 
     return (data+x*nn); 
    } 
}; 

С его помощью вы можете использовать

array2d arr(10,10); 
arr[5][7] = 1; 
Смежные вопросы