При входе в функцию в стек добавляется новый кадр стека.Во фрейме стека хранятся все auto (не статические переменные, объявленные в функции).Когда мы покидаем функцию, возвращаемое значение помещается в регистр (обычно R0) в CPU, а затем указатель стека уменьшается, чтобы удалить кадр стека.Затем мы возвращаем управление в точку, где мы вызвали функцию, и получаем возвращаемое значение из регистра.
Так что в этом случае у вас есть int arr[5]
, когда программа входит в функцию, добавляется новый кадр стекав стек.В этом стековом фрейме есть память на 5 целых чисел в массиве, переменная arr
теперь действительно эквивалентна указателю на первый элемент в массиве.Когда вы возвращаете переменную arr
, вы возвращаете указатель на данные в фрейме стека, когда функция завершается и вы возвращаетесь к предыдущей функции, указатель стека затем уменьшается, чтобы удалить фрейм стека только что вышедшей функции.
Указатель по-прежнему указывает на то место в памяти, где ранее был выделен массив.Поэтому при увеличении стека память, на которую указывает arr
, будет перезаписана.Изменение данных, на которые указывает возвращаемое значение, может привести к некоторым «захватывающим» вещам, поскольку мы не знаем, когда память используется сейчас.
Пример массива и указателя:
char arr[5];
char * ptr = arr;
В этом случае компилятор знает размер arr
и не знает размер ptr
, поэтому мы можем выполнить sizeof (arr), и компилятор выполнит вычисление во время компиляции.Когда дело доходит до времени выполнения, они являются эквивалентными значениями в памяти.