В C99 Существуют массивы переменной длины (variable-length arrays), которые могут быть использованы в качестве локальных переменных. Память под них выделяется динамически со стека.
GCC позволяет также использовать такие массивы в C++. Элементы таких массивов инициализируются конструктором по умолчанию, также вызываются должным образом деструкторы. Инициализация чем-либо, кроме конструктора по умолчанию, не возможна.
Подобного рода массивы полезны для хранения некоторых промежуточных данных переменной длины, когда ожидаемое количество элементов не велико и выделение памяти из кучи слишком накладно.
К сожалению в C++ такие массивы не являются частью стандарта. Если нужно выделить локальный блок памяти переменной длины, приходится или использовать std::vector, или буфер фиксированного размера, с использованием того же std::vector, если размера не хватает.
Поскольку подобные массивы являются весьма полезными, предлагаю сделать их частью стандарта C++.
Но в том виде, в котором они сейчас реализованы в GCC, их использовать не очень хорошо. В текущей реализации есть ряд проблем.
Память на стеке (очевидно) весьма ограничена. Можно её исчерпать, если объявленный массив переменной длины слишком большой. Поэтому предлагаю, дабы минимизировать вероятность переполнения стека, разрешить реализации на своё усмотрение выделять памяти из кучи (оператором new[]). Например, если размер аллокации выше порогового - выделять память из кучи, иначе - на стеке. При этом компилятор должен сам вставлять код, который освободит должным образом память, ранее выделенную из кучи (оператором delete[]). В зависимости от целевой платформы/среды память может всегда выделяться только со стека или только из кучи.
Ещё одна проблема массивов переменной длины в реализации от GCC - негибкость инициализации. Эту негибкость предлагается устранить, добавив больше вариантов инициализации:
Инициализация значением-заполнителем. В качестве инициализатора предоставляется одно значение внутри {}, оно будет скопировано (конструктором копирования) во все элементы массива.
Инициализация парой итераторов [begin; end) внутри {}. Элементы массива инициализируются элементами, доступными через итераторы в этом диапазоне. Расстояние между парой итераторов должно быть равно количеству элементов массива, иначе - неопределённое поведение.
В C99 Существуют массивы переменной длины (variable-length arrays), которые могут быть использованы в качестве локальных переменных. Память под них выделяется динамически со стека.
GCC позволяет также использовать такие массивы в C++. Элементы таких массивов инициализируются конструктором по умолчанию, также вызываются должным образом деструкторы. Инициализация чем-либо, кроме конструктора по умолчанию, не возможна.
Подобного рода массивы полезны для хранения некоторых промежуточных данных переменной длины, когда ожидаемое количество элементов не велико и выделение памяти из кучи слишком накладно.
К сожалению в C++ такие массивы не являются частью стандарта. Если нужно выделить локальный блок памяти переменной длины, приходится или использовать
std::vector
, или буфер фиксированного размера, с использованием того жеstd::vector
, если размера не хватает.Поскольку подобные массивы являются весьма полезными, предлагаю сделать их частью стандарта C++.
Но в том виде, в котором они сейчас реализованы в GCC, их использовать не очень хорошо. В текущей реализации есть ряд проблем.
Память на стеке (очевидно) весьма ограничена. Можно её исчерпать, если объявленный массив переменной длины слишком большой. Поэтому предлагаю, дабы минимизировать вероятность переполнения стека, разрешить реализации на своё усмотрение выделять памяти из кучи (оператором
new[]
). Например, если размер аллокации выше порогового - выделять память из кучи, иначе - на стеке. При этом компилятор должен сам вставлять код, который освободит должным образом память, ранее выделенную из кучи (операторомdelete[]
). В зависимости от целевой платформы/среды память может всегда выделяться только со стека или только из кучи.Ещё одна проблема массивов переменной длины в реализации от GCC - негибкость инициализации. Эту негибкость предлагается устранить, добавив больше вариантов инициализации:
{}
, оно будет скопировано (конструктором копирования) во все элементы массива.{}
. Элементы массива инициализируются элементами, доступными через итераторы в этом диапазоне. Расстояние между парой итераторов должно быть равно количеству элементов массива, иначе - неопределённое поведение.