void PrintArray()
{
int a[4] = {4,3,1,5};
for(int i=0; i<4; i++)
cout<<a[i];
}
Что именно происходит с памятью, выделенной для переменной-указателя ‘a’ и 4-целочисленного блока, на который указывает ‘a’ после завершения вызова этой функции?
Освобождается ли память переменной блока и указателя или она создает какую-то утечку памяти?
a
не является статической переменной, это automatic
переменная, из проект стандарта C99 раздел 6.2.4
Длительность хранения предметов п.4 говорит:
Объект, идентификатор которого объявлен без связи и без класса хранения
Спецификатор static имеет автоматическую продолжительность хранения.
В параграфы 3 это описывает время жизни static
как время жизни программы и в пункт 5 говорит:
Для такого объекта, у которого нет типа массива переменной длины, его время жизни увеличивается
от входа в блок, с которым он связан, до тех пор, пока выполнение этого блока не закончится в
тем не мение. […]
Другими словами, для автоматической переменной ее время жизни распространяется на ее область действия, в данном случае a
S сфера является функцией PrintArray
и хранилище, связанное с ним, освобождается после выхода из этой области.
Для C ++ соответствующий раздел из проект стандарта является 3.7.3
Автоматическая продолжительность хранения пункт 1 говорит:
Переменные области видимости, явно объявленные в регистре или не объявленные явно как статические или внешние, имеют автоматическую продолжительность хранения. Хранение этих сущностей длится до тех пор, пока блок, в котором они созданы, не выйдет.
Автоматические переменные не являются статичными, они располагаются в конце своей области (в конце функции). Статическая переменная сохранится, она сохранит свое значение, даже если она вызывается в функции. Вот ссылка о внешние / статические переменные для дальнейших деталей.
Память не течет. Он не выделяется в куче. Теперь, вероятно, здесь задействованы 2 разных места памяти.
{ 4,3,1,5 }
инициализатор сохранен. Обычно такие инициализаторы хранятся в сегменте данных. Во встроенной системе это может быть только для чтения флэш. На ПК или чем-то еще, это будет область ОЗУ, которая инициализируется с образом вашей программы (например, EXE) и не изменяется. После выхода из функции она все еще там. Но это не утечка — просто часть памяти вашей программы (некоторые могут сказать, статическая память).a[]
в PrintArray()
сфера действия. Компилятор выделяет некоторое пространство стека и затем копирует значения в начале функции из сегмента данных. Это обычно происходит, так что если вы измените какой-либо из элементов в a[]
, он влияет только на этот массив для данного вызова функции. когда PrintArray()
вызывается снова, исходный инициализатор не изменяется и доступен для повторного использования. Было бы странно / неожиданно, если последующие вызовы PrintArray()
инициализирован к чему-то помимо { 4,3,1,5 }
из-за предыдущего вызова, изменяющего значение. Тем не менее, вы не изменяете его здесь, поэтому вполне вероятно, что оптимизации могут ничего не размещать в стеке. YMMV. Если предположить, a[]
находится в стеке, он будет освобожден автоматически (следовательно, auto
переменная) при выходе из функции.Конечно, именно так что происходит, зависит от вашего компилятора, компоновщика, настроек (особенно оптимизаций) и цели.
В C такой автоматический объект, как a
сбрасывается на выходе из блока, где он был объявлен.
переменная-указатель ‘a’ и 4-х целочисленный блок, на который указывает ‘a’
Во-первых, нам нужно прояснить основное заблуждение здесь. a
является не отдельная переменная-указатель, отличная от массива из 4 элементов; a
является массив из 4 элементов. Адрес a
и адрес a[0]
это одно и то же. В большинстве случаев выражение a
преобразуется из типа «4-элементный массив int
указатель на int
«, а значение выражения является адресом первого элемента в массиве.
Чтобы ответить на вопрос, так как a
был объявлен в блоке и без static
ключевое слово, оно имеет продолжительность автоматического хранения, Это означает, что память, занимаемая массивом, освобождается, когда вы покидаете ограничивающую область (в данном случае тело функции).