variable - ¿Por qué las matrices estáticas no necesitan ser liberadas?
static variable java (5)
Las variables estáticas continúan existiendo incluso después de que el bloque en el que están definidas termina. Por lo tanto, el valor de una variable estática en una función se conserva entre las llamadas a funciones repetidas a la misma función. El alcance de las variables automáticas estáticas es idéntico al de las variables automáticas, es decir, es local al bloque en el que está definido; sin embargo, el almacenamiento asignado se vuelve permanente durante la duración del programa. Las variables estáticas pueden inicializarse en sus declaraciones; sin embargo, los inicializadores deben ser expresiones constantes, y la inicialización se realiza solo una vez en el momento de la compilación cuando se asigna memoria para la variable estática. - fuente
La matriz estática o las variables no se liberarán cuando el control salga de esa función. El alcance de la variable estática es local para la función en la que se declara, pero su duración es en todo el programa.
Me pregunto por qué las matrices estáticas no necesitan ser liberadas. Sé que al crear una matriz dinámica, por ejemplo
int *p;
p = malloc(10*sizeof(int));
tenemos que liberar la memoria asignada mediante:
free(p);
Y para una matriz estática en una función, la matriz estática se liberará automáticamente cuando se complete la función llamada.
Lo que no entiendo es: al devolver una matriz estática usando una función como esta:
int *subFunc(){
static int a[5] = {1,2,3,4,5};
return a;
}
int main(){
int *p;
p = subFunc();
}
Si la matriz estática se libera automáticamente después de completar la ejecución, ¿cómo podemos seguir accediendo correctamente a los valores de la matriz estática?
Me pregunto por qué las matrices estáticas no necesitan ser liberadas.
Lo que no está asignado por una función de gestión de memoria (malloc, calloc), como
int a[5]
no necesita ser explícitamente cuidado para la liberación .Las variables estáticas, como
static int a[5]
sirven para ser accesibles dentro del alcance local (conservan sus valores entre las llamadas posteriores de la función local). Se crean en el momento de la compilación exactamente para este propósito, tienen un tiempo de vida del programa, por lo que no sería una consideración lógica liberarlos, incluso si fuera posible, y no lo es .Todo lo demás está siendo explicado magistralmente en otras respuestas.
Y para una matriz estática en una función secundaria, la matriz estática se liberará automáticamente cuando se complete la sub función llamada.
Eso no es verdad. Las matrices estáticas no se crean cuando ingresas a la función, y no se destruyen cuando la dejas.
Una variable estática y los datos que contiene se parecen mucho a una variable global . Lo único que es local para la función es el nombre . (Escuchará a las personas hablar sobre el "alcance" de la variable, esto significa "¿dónde puedo usar el nombre para referirme a él?")
Entonces, cuando estás pensando en la vida de una matriz estática, puedes reemplazar mentalmente:
int *subFunc(){
static int a[5] = {1,2,3,4,5};
return a;
}
con
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;
}
y luego pretender que nadie más en su programa puede tocar esa variable global.
Si la matriz estática se libera automáticamente después de completar la ejecución, ¿cómo podemos seguir accediendo correctamente a los valores de la matriz estática?
No, no es así. static
variables static
se inicializan antes de iniciar main()
y su duración es la ejecución completa del programa. Por lo tanto, pueden return
desde las funciones (en las que están definidas) y todavía se puede acceder. No son locales (a las funciones) que se agotan cuando la función termina la ejecución.
Relacionado, citando de C11
, capítulo §6.2.4
Un objeto cuyo identificador se declara sin el especificador de clase de almacenamiento
_Thread_local
, y con enlace externo o interno o con el especificador de clase de almacenamientostatic
, tiene una duración de almacenamiento estático. Su duración es la ejecución completa del programa y su valor almacenado se inicializa solo una vez, antes del inicio del programa.
En cuanto al alcance de una variable static
dentro de una función, sí, está limitado a la función en sí, como se menciona en el capítulo §6.2.1,
[...] Si el declarador o especificador de tipo que declara el identificador aparece dentro de un bloque o dentro de la lista de declaraciones de parámetros en una definición de función, el identificador tiene alcance de bloque, que termina al final del bloque asociado. [...]
Eso significa, obviamente, que no se puede usar a
matriz fuera de subFunc()
, ya que a
no está visible fuera de subFunc()
.
Sin embargo, cuando return
la matriz (devolver una matriz provoca una disminución en el puntero al primer elemento de la matriz, FWIW), ya que la vida útil de la matriz static
es la ejecución completa del programa, accediendo al puntero devuelto (seguramente, dentro de límites) es perfectamente válido y legal.
Static variables
dentro de una función, usualmente usadas para mantener algunos datos en el alcance de la función en múltiples llamadas para la misma . Se inicializan antes de main () y su duración es como la ejecución completa del programa. Entonces, eso no tendría sentido si fueran liberados después de salir de la función. Si los libera, se bloqueará la próxima vez que llame a la función porque no se hará referencia a ellos.