Почему статические массивы не нужно освобождать?

мне интересно, почему статические массивы не нужно освобождать? Я знаю, что при создании динамического массива, например,

int *p;
p = malloc(10*sizeof(int));

мы должны освободить выделенную память с помощью:

free(p);

и для статического массива в функции статический массив будет автоматически освобожден, когда вызываемая функция будет выполнена.

чего я не понимаю: при возврате статического массива с помощью такой функции:

int *subFunc(){
    static int a[5] = {1,2,3,4,5};
    return a;
}

int main(){
    int *p;
    p = subFunc();
}

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

5 ответов


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

нет, все не так. static переменные инициализируются перед началом main() и его время жизни - это все выполнение программы. Итак, они могут быть returned из функций (в которых они определены) и все еще могут быть доступны. Они не местные (в функции), который выходит из срока службы, когда функция завершает выполнение.

обзоры, цитирую C11 глава §6.2.4

объект, идентификатор которого объявлен без спецификатора класса хранения _Thread_local, и или с внешним или внутренним рычагом или с хранени-типом спецификатор static, имеет статическую длительность хранения. Его продолжительность жизни-это полное выполнение программа и ее сохраненное значение инициализируются только один раз, до запуск программы.

о область of a static переменная внутри функции, да, она ограничена самой функцией, как упоминалось в главе §6.2.1,

[...] Если Декларатор или спецификатор типа объявляет идентификатор, отображаемый внутри блока или в списке объявлений параметров в определение функции, идентификатор имеет область блока, которая завершается в конце связанный блок. [...]

это означает, что, очевидно, вы не можете использовать array a за пределами subFunc(), as a не видимого за пределами subFunc().

Впрочем, когда вы return массив (возврат массива вызывает распад указателя на первый элемент массива, FWIW), как время жизни static array-это все выполнение программы, доступ к возвращенному указателю (конечно, в пределах) является абсолютно допустимым и законным.


статические переменные продолжают существовать даже после блока, в котором они определены завершает. Таким образом, значение статической переменной в функция сохраняется между повторными вызовами функции к тому же функция. Область статических автоматических переменных идентична этой автоматических переменных, т. е. он является локальным для блока, в котором он находится определено; однако выделенное хранилище становится постоянным для продолжительность программы. Статические переменные могут быть инициализировано в их объявления; однако инициализаторы должны быть постоянными выражениями, и инициализации выполняется только один раз во время компиляции, когда память выделено для статической переменной. - источник

статический массив или переменные не будут освобождены, когда контроль выходит из этой функции. Область статической переменной локальна для функции, в которой она объявлена, но ее время жизни-в течение всей программы.


и для статического массива в подфункции статический массив будет автоматически освобожден, когда вызываемая подфункция будет выполнена.

Это неправда. Статические массивы не создаются при входе в функцию и не уничтожаются при выходе из нее.

статическая переменная и данные внутри нее действительно очень похоже на глобальную переменную! Единственное, что локальные функции имя. (Ты ... услышьте, как люди говорят о " области "переменной-это означает" где я могу использовать имя для ссылки на него.")

поэтому, когда вы думаете о жизни статического массива, вы можете мысленно заменить:

int *subFunc(){
    static int a[5] = {1,2,3,4,5};
    return a;
}

С

int ONLY_USE_ME_INSIDE_SUBFUNC__a[5] = {1,2,3,4,5};  /* global variable */

int *subFunc(){
    int * a = ONLY_USE_ME_INSIDE_SUBFUNC__a;  /* a is the same as the global */
    return a;
}

а затем притворитесь, что никто другой в вашей программе не может коснуться этой глобальной переменной.


мне интересно, почему статические массивы не нужно освобождать?

  1. все, что не выделяется функцией управления памятью (malloc, calloc), например int a[5] не нужно явно заботиться о освобождение.

  2. статические переменные, такие как static int a[5] служат для доступа в локальной области (они сохраняют свои значения между последующими вызовами локальной функции). Они создаются при компиляции время именно для этой цели у них есть программа lifetime, поэтому не было бы логичным соображением освободить их, даже если бы это было возможно,это не.

  3. все остальное мастерски объясняется в других ответах.


Static variables внутри функции, обычно используется для поддержания некоторых данных в области функции над несколькими вызовами для него. Они инициализируются перед main (), и их время жизни-это полное выполнение программы. Таким образом, это не имело бы смысла, если бы они были освобождены после выхода из функции. Если вы освободите их, вы разобьетесь при следующем вызове функции, потому что они не будут ссылаться.