Страницы

Поиск по вопросам

воскресенье, 29 декабря 2019 г.

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

#cpp #указатели #динамические_массивы


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

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

#include 
using namespace std;

int main()
{
    int size;
    cin >> size;

    int array[size];

    cout << sizeof(array)/sizeof(array[0]) << endl;

    return 0;
}


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


Ответы

Ответ 1



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

Ответ 2



В учебниках по C++ пишут, что динамические массивы нужны, когда заранее неизвестны размеры этих массивов Да, это одна из причин. Но, возможно добавить какие-то ограничения в программу, чтобы минимизировать "ущерб" от отсутствия таких массивов. Так в чем подвох, почему нужно делать с указателями а так, как я сделал нельзя? Также важно время хранения этого массива. Создавая массив на стеке его время хранения получается автоматическим, и массив будет уничтожен при выходе из функции. Что мы получаем при динамическом выделении памяти: Можем определиться с размером во время выполнения. Контроль времени жизни объектов в этой памяти. Больший объем памяти, нежели объем "стандартного" стека. Подробнее здесь: Определение объектов в C++ и все работает Здесь возможны несколько вариантов. Ваш компилятор поддерживает возможность создания таких массивов, реализуя расширения языка, например, расширение VLA (Variable-Length Arrays) в GCC. Компилятор поддерживает возможность RSA (Runtime-Sized Arrays), которую хотели добавить в C++14, но так и не добавили. Но разработчики поспешили её добавить в компилятор и Вам досталась та самая версия этого компилятора. То есть на текущий момент возможности создавать такие массивы в языке нет. Опять же, вполне вероятно, что лучшим вариантом будет воспользоваться одним из стандартных контейнеров, или, хотя бы умными указателями.

Ответ 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; } Напишите программу использовав то одну, то другую функцию и убедитесь, что вторая на самом деле является вздором. Вот о чем речь, когда говорится о неизвестном размере, плюс ко всему сказанному ранее.

Комментариев нет:

Отправить комментарий