Зачем нужны динамические массивы в C++?

212
16 апреля 2018, 00:14

В учебниках по C++ пишут, что динамические массивы нужны, когда заранее неизвестны размеры этих массивов. Потом идет объяснение, как выделять указателями память из кучи, затем ее надо освобождать и т.д.

Но я попробовал сделать без указателей, вот так:

#include <iostream>
using namespace std;
int main()
{
    int size;
    cin >> size;
    int array[size];
    cout << sizeof(array)/sizeof(array[0]) << endl;
    return 0;
}

и все работает. Память, получается, выделяется динамически и без указателей. Т.е. во время написания программы, мы не знали размера массива а ввели его уже во время выполнения программы. Так в чем подвох, почему нужно делать с указателями а так, как я сделал нельзя?

Answer 1

Это работает только в конкретном компиляторе, в котором реализовано данное расширение. Стандартом С++ такое не предусмотрено, только С (да и то реализация не является строго необходимой).

Это примерно как если бы вам говорили, что молоток - только для забивания гвоздей, а вы бы возражали - а вот у меня молоток такой, что я им могу еще и шурупы вертеть. Поверю, что у вас молоток с ручкой в виде отвертки (сам такой в школе на трудах делал :)), но это не значит, что молоток вообще приспособлен для такой деятельности...

P.S. И еще - динамические массивы нужны не только тогда, когда количество элементов неизвестно заранее. Но еще и для больших размеров, например, или для строго регулируемого времени жизни - словом, неизвестный заранее размер - не единственная причина их использования.

Answer 2

В учебниках по C++ пишут, что динамические массивы нужны, когда заранее неизвестны размеры этих массивов

Да, это одна из причин. Но, возможно добавить какие-то ограничения в программу, чтобы минимизировать "ущерб" от отсутствия таких массивов.

Так в чем подвох, почему нужно делать с указателями а так, как я сделал нельзя?

Также важно время хранения этого массива. Создавая массив на стеке его время хранения получается автоматическим, и массив будет уничтожен при выходе из функции. Что мы получаем при динамическом выделении памяти:

  1. Можем определиться с размером во время выполнения.
  2. Контроль времени жизни объектов в этой памяти.
  3. Больший объем памяти, нежели объем "стандартного" стека.

Подробнее здесь: Определение объектов в C++

и все работает

Здесь возможны несколько вариантов.

  1. Ваш компилятор поддерживает возможность создания таких массивов, реализуя расширения языка, например, расширение VLA (Variable-Length Arrays) в GCC.
  2. Компилятор поддерживает возможность RSA (Runtime-Sized Arrays), которую хотели добавить в C++14, но так и не добавили. Но разработчики поспешили её добавить в компилятор и Вам досталась та самая версия этого компилятора.

То есть на текущий момент возможности создавать такие массивы в языке нет. Опять же, вполне вероятно, что лучшим вариантом будет воспользоваться одним из стандартных контейнеров, или, хотя бы умными указателями.

Answer 3

Допустим я хочу написать функцию создания массива по заданному размеру для заданного указателя. Я напишу так:

int* new_array(int* p, size_t sz)
{        
    p = new int[sz];
    return p;
}

А теперь я напишу без выделения памяти в динамической области (как вы показали):

int* fudge(int* p, size_t sz)
{
    if(sz > sizeof(p) / sizeof(p[0])) {
        int m[sz];
        p = m;
    }
    return p;
}

Напишите программу использовав то одну, то другую функцию и убедитесь, что вторая на самом деле является вздором. Вот о чем речь, когда говорится о неизвестном размере, плюс ко всему сказанному ранее.

READ ALSO
Взаимодейстие с клавиатурой на C/C++

Взаимодейстие с клавиатурой на C/C++

1-2 дня назад я задал вопрос, но не совсем корректный, поэтому сейчас я постараюсь поставить его более правильноДопустим, есть игра, в которой...

157
ГПСЧ с помощью Mersenne twister (диапазон значений)

ГПСЧ с помощью Mersenne twister (диапазон значений)

Добрый день, друзьяПодскажите, пожалуйста, алгоритм применения вихря Мерсенна в заданном диапазоне значений (н-р 1-100), можно и реализацию...

206
Вывод данных из одного компонента в других Angular 5

Вывод данных из одного компонента в других Angular 5

Проблема в следующемЕсть родительский компонент

149