Как правильно использовать массив Dynami c? - PullRequest
1 голос
/ 05 марта 2020

Итак, я пытаюсь использовать динамический c массив для своей программы, и я не знаю, правильно ли я это делаю. Должен ли я использовать const int или только int?

int size = 1;
    int *num1 = new int [size];
    int *num2 = new int [size]; 

или

const int size = 1;
        int *num1 = new int [size];
        int *num2 = new int [size]; 

Ответы [ 2 ]

6 голосов
/ 05 марта 2020

Если размер является константой времени компиляции, из которой вы хотите создать «массив», тогда я предлагаю std::array, как в

std::array<int, 1> num1;

Если размер неизвестно во время компиляции, тогда используйте std::vector, как в

std::vector<int> num1(size);

И если у вас действительно есть для использования явного динамического выделения c затем выберите интеллектуальные указатели например std::unique_ptr, например

auto num1 = std::make_unique<int[]>(size);

Что касается переменной size, равной const, constexpr, не квалифицированы вообще, или если вам следует использовать буквальное значение непосредственно при распределении, тогда оно действительно зависит от варианта использования, доступности значения и личных предпочтений.

С другой стороны, для размера Вы должны использовать тип size_t вместо int. Большинство программистов сразу поймут, что при использовании size_t переменная используется для хранения размера. В противном случае, если вы используете int, это может быть любое произвольное целочисленное значение. Кроме того, size_t является типом без знака , поэтому он не допускает отрицательных чисел, что является одной из причин возникновения проблем.

1 голос
/ 05 марта 2020

Я видел, как вы задали несколько вопросов об этом сейчас, поэтому я хочу показать вам разницу между изменением размера динамического массива c и использованием std::vector, который упаковывает все необходимые вам функции. в блоке динамического размера непрерывной памяти.

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

int number = 0;
std::size_t array_size = 0; // we need to track the size of the thing
int *array = nullptr; // nothing in here yet

std::cout << "Enter a number, non-number to exit: ";
while (std::cin >> number)
{
   // we need to request more memory
   ++array_size;
   int *new_array = new int[array_size];

   // we have to copy the old array to the new array
   // fun note: as pointed out in the comments below, using memcpy on
   // either src or dest == nullptr is undefined behavior. Just goes to
   // show how hard it is to get something like this correct.
   // Don't do this when we have perfectly good STL containers!
   std::memcpy(new_array, array, (array_size - 1) * sizeof(int));

   // delete the old array, if it exists (we can safely call delete on a nullptr)
   delete[] array;

   // assign the new block of memory to array
   array = new_array;

   // add the retrieved element to array
   array[array_size - 1] = number;

   std::cout << "Enter a number, non-number to exit: ";
}
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');

// output the array
for (std::size_t i = 0; i < array_size; i++)
{
    std::cout << array[i] << "\n";
}

// all done, delete the memory that was allocated
delete[] array;
array = nullptr; // not strictly required, but can prevent us from accidentally deleting the same block of memory twice, which would be bad

Мы можем сделать то же самое, используя std::vector:

int number;
std::vector<int> vec; // this is a vector that holds ints, it tracks its own size and memmory

std::cout << "Enter a number, non-number to exit: ";
while (std::cin >> number)
{
    vec.push_back(number); // all done

    std::cout << "Enter a number, non-number to exit: ";
}
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');

for (std::size_t i = 0; i < vec.size(); i++)
{
    std::cout << vec[i] << "\n";
}

// or we can used range-based for loops, which are awesome
for (auto& v : vec)
{
    std::cout << v << "\n";
}

Обратите внимание, что в примере std::vector я выводил содержимое std::vector дважды, просто чтобы показать, что у нас есть опция для перебора вектора, который недоступен для int *. Нам не нужно отслеживать память. Нам не нужно new и delete. Когда текущая область действия программы выходит (например, если это функция), вызывается деструктор std::vector, который очищает память для нас.

ИСПОЛЬЗОВАТЬ ВЕКТОРЫ !!!

...