2D динамический массив памяти в переполнении стека

Несколько дней назад я узнал о создании двумерных массивов памяти из Интернета, все работает отлично. Для доступа к массиву мы просто используем 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 ;

6

Решение

поскольку a[b] просто *(a + b) Вы, конечно, можете сделать это:

*(*(matrix + i) + j)

Во всяком случае, те, new распределения подвержены ошибкам. Если один из вложенных newS броски, то у вас будет утечка. Попробуйте использовать std::vector вместо.

3

Другие решения

Отвечая на ваш второй вопрос: когда вы выделяете двумерный массив с помощью следующего кода

// 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), что не имеет смысла.

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

5

Примерно так будет работать:

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);
}
}
2

Да, вы используете сложение указателя, но вам нужно понять, как распределяется память. Скажем, x — указатель на первый элемент массива целых, если вы хотите получить доступ к x [2], вы можете использовать * (x + 2). Однако с матрицами это может привести к путанице, и у вас гораздо больше шансов получить неверные индексы в вашей матрице, если вы сделаете это, поэтому я бы не советовал.

1

Вы могли бы сделать *(*(matrix+i)+j), Это должно быть эквивалентно скобочной записи. То, что происходит с обоими обозначениями просто арифметика указателей.

0
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector