Несколько дней назад я узнал о создании двумерных массивов памяти из Интернета, все работает отлично. Для доступа к массиву мы просто используем matrix[i][j]
Однако есть ли способ разыменовать этот 2D-массив с помощью *
обозначение вместо []
для ввода, а также другие методы?
Первые вопросы решены, я могу использовать *(*(matrix + i) + j)
Теперь у меня есть еще один вопрос, последний сегмент кода — освободить выделенную память (я также получил ее из интернета), но я не понимаю, почему я не могу просто использовать delete [] matrix
?
int **matrix;
// dynamically allocate an array
matrix = new int *[row];
for (int count = 0; count < row; count++)
{
matrix[count] = new int[col];
}
// input element for matrix
cout << endl << "Now enter the element for the matrix...";
for (int i=0; i < row; i++)
{
for (int j=0; j < col; j++)
{
cout << endl << "Row " << (i+1) << " Col " << (j+1) << " :";
cin >> matrix[i][j]; // is there any equivalent declaration here?
}
}
// free dynamically allocated memory
for( int i = 0 ; i < *row ; i++ )
{
delete [] matrix[i] ;
}
delete [] matrix ;
поскольку a[b]
просто *(a + b)
Вы, конечно, можете сделать это:
*(*(matrix + i) + j)
Во всяком случае, те, new
распределения подвержены ошибкам. Если один из вложенных new
S броски, то у вас будет утечка. Попробуйте использовать std::vector
вместо.
Отвечая на ваш второй вопрос: когда вы выделяете двумерный массив с помощью следующего кода
// dynamically allocate an array
matrix = new int *[row];
for (int count = 0; count < row; count++)
matrix[count] = new int[col];
вы фактически выделяете один массив указателей (ваша матричная переменная, которая является двойным указателем) и массивы целых чисел «row» (каждый из которых представляет одну строку в вашей матрице размера «col»), которые matrix[0]
, matrix[1]
и т. д. до matrix[row-1]
,
Таким образом, когда вы хотите освободить свою матрицу, вам сначала нужно освободить каждую строку (массивы, размещенные в цикле), а затем массив, содержащий строки. В вашем случае код, который вы используете для освобождения матрицы, частично неверен и должен быть похож на следующий:
// free dynamically allocated memory
for( int i = 0 ; i < row ; i++ )
{
//first we delete each row
delete [] matrix[i] ;
}
//finally, we delete the array of pointers
delete [] matrix ;
Удаление в цикле освободит каждую строку вашей матрицы, а окончательное удаление освободит массив строк. В вашем коде вы используете удалить row
раз на ваш двойной указатель (matrix
), что не имеет смысла.
Наконец, использование одного удаления для двойного указателя является неправильным, потому что это приведет к утечке памяти, поскольку вы не освобождаете память, выделенную для каждой строки, а только указатели, ссылающиеся на нее.
Примерно так будет работать:
int **matrix;
// dynamically allocate an array
matrix = new (std::nothrow) int *[row];
if (matrix == NULL)
{
// handle the error
}
for (int count = 0; count < row; count++)
{
*(matrix + count) = new (std::nothrow) int[col];
if (matrix[count] == NULL)
{
// handle the error
}
}
cout << "\nNow enter the element for the matrix...";
for (int i=0; i < row; i++)
{
for (int j=0; j < col; j++)
{
cout << "\nRow " << (i+1) << " Col " << (j+1) << " :";
cin >> *(*(matrix + i) + j);
}
}
Да, вы используете сложение указателя, но вам нужно понять, как распределяется память. Скажем, x — указатель на первый элемент массива целых, если вы хотите получить доступ к x [2], вы можете использовать * (x + 2). Однако с матрицами это может привести к путанице, и у вас гораздо больше шансов получить неверные индексы в вашей матрице, если вы сделаете это, поэтому я бы не советовал.
Вы могли бы сделать *(*(matrix+i)+j)
, Это должно быть эквивалентно скобочной записи. То, что происходит с обоими обозначениями просто арифметика указателей.