ОБНОВЛЕНИЕ: фрагмент кода C ++ - PullRequest
1 голос
/ 15 февраля 2009

Приветствую еще раз, и еще раз спасибо всем, кто предоставил ответы на первый вопрос. Следующий код обновляется, чтобы включить две функции в соответствии с назначением.

Чтобы увидеть оригинальный вопрос, нажмите здесь .

Я довольно уверен, что это соответствует требованиям задания, но еще раз я был бы очень признателен за любую помощь. Правильно ли я изменил операторы удаления? Еще раз спасибо.

#include<iostream>
#include<string>

int** createArray(int, int);
void deleteArray(int*[], int);

using namespace std;

int main()
{
    int nRows;
    int nColumns;

    cout<<"Number of rows: ";
    cin>>nRows;

    cout<<"Number of columns: ";
    cin>>nColumns;

    int** ppInt = createArray(nRows, nColumns);

    deleteArray(ppInt, nRows);
}

int** createArray(int nRows, int nColumns)
{
    int** ppInt = new int*[nRows];

    for (int nCount = 0; nCount < nRows; nCount++)
    {
        ppInt[nCount] = new int[nColumns];
    }

    return ppInt;
}

void deleteArray(int** nPointer, int nRows)
{
    for (int nCount = 0; nCount < nRows; nCount++)
    {
        delete[] nPointer[nCount];
    }

    delete[] nPointer;
}

P.S. Вот сама документация по назначению, на случай, если она поможет:

(1) Разработать и реализовать функцию для выделения памяти для двумерного целочисленного массива: предполагается, что функция принимает два целых числа в качестве параметров, одно для числа строк и одно для числа столбцов. Вам нужно использовать «новый» оператор в этой функции. Помните, что нам нужно сначала создать массив указателей. Затем для каждого указателя в этом массиве нам нужно создать массив целых чисел. Предполагается, что эта функция возвращает указатель, который указывает на двумерный целочисленный массив.

(2) Разработать и реализовать функцию для выделения памяти для этого двумерного массива: предполагается, что функция имеет два параметра (указатель, который указывает на двумерный целочисленный массив, а другой - число строк в массиве). В этой функции вы должны освободить память для этого двумерного массива с помощью оператора «delete». Сначала вы должны удалить каждую строку (массив целых чисел), а затем удалить массив указателей.

Ответы [ 4 ]

4 голосов
/ 15 февраля 2009

Код выглядит хорошо.

Однако есть некоторые проблемы, которые вы, возможно, захотите решить, для нас, людей:

  1. В сигнатурах функций (объявлениях) отсутствуют имена параметров. Более подходит:

    int** createArray(int rows, int columns);
    void deleteArray(int** array, int rows);
    
  2. Ваши имена функций не слишком описательны в отношении того, что они действительно создают / удаляют. create2DArray будет более разумным выбором, например.

  3. Ваши n префиксы к вашим переменным ранили мне глаза. numRows или rowCount более читабельно.
  4. Точно так же ppInt - это безумие. Попробуйте array (для nPointer также, для согласованности). (К сожалению, вы не можете написать 2dArray.)
  5. Использование i в качестве счетчика цикла встречается чаще, чем nCount или подобное (особенно для индексов массива). Я предлагаю вам использовать это вместо.

Некоторые вещи, которые идут выше и дальше, для вашей личной практики:

  1. Создайте класс, который принимает rows и cols в качестве аргументов своего конструктора. Убедитесь, что массив освобожден автоматически.
  2. Используйте std::vector и создайте функцию-член resize для вашего класса. Обратите внимание, что это отличается от первоначального вопроса, в котором задавались указатели.
  3. Создайте функцию copy и clone для копирования данных в другой двумерный массив (возможно, другого размера!) Или клонирования существующего массива.
1 голос
/ 15 февраля 2009

Все нормально.

Проблема в том, что вы не думаете о безопасности исключений в своем коде.

int** ppInt = new int*[nRows];   // ALLOC 1

for (int nCount = 0; nCount < nRows; nCount++)
{
        ppInt[nCount] = new int[nColumns]; // ALLOC 2
}

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

Например.
Вы терпите неудачу при четвертом вызове ALLOC 2. Затем вы теряете память из ALLOC 1 и первые три вызова ALLOC 2. Теперь в вашей ситуации код настолько тривиален, что, вероятно, не имеет значения. НО это та вещь, о которой вы всегда должны помнить при написании кода на C ++.

Что произойдет здесь, если будет выброшено исключение, какие ресурсы будут утечки, какие ресурсы не будут очищены правильно.

Я думаю, вам следует подумать об обёртывании 2D-массива внутри класса, чтобы гарантировать правильное распределение и удаление памяти даже при наличии исключений.

0 голосов
/ 15 февраля 2009

Для "deleteArray" ваш прототип и определение не совсем совпадают:

void deleteArray(int*[], int);
void deleteArray(int** nPointer, int nRows)

Они имеют одно и то же значение, но для ясности, я думаю, было бы лучше, чтобы они были одинаковыми (в пользу `int ** ', чтобы подчеркнуть тот факт, что вы передаете указатели) для согласованности.

Также включите имена аргументов в прототип.

0 голосов
/ 15 февраля 2009

Выглядит разумно для меня.

Хотя я не уверен, что задам совершенно новый вопрос. Это могло бы быть лучше в качестве поправки к оригиналу.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...