31 votes

Pourquoi les tableaux statiques ne doivent-ils pas être libérés ?

Je me demande pourquoi les tableaux statiques n'ont pas besoin d'être libérés ? Je sais que lors de la création d'un tableau dynamique, par ex.

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

nous devons libérer la mémoire allouée en utilisant :

free(p);

Et pour un tableau statique dans une fonction, le tableau statique sera automatiquement libéré lorsque la fonction appelée sera terminée.

Ce que je ne comprends pas, c'est que lorsque l'on renvoie un tableau statique en utilisant une fonction comme celle-ci :

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

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

Si le tableau statique est automatiquement libéré à la fin de l'exécution, comment pouvons-nous encore accéder correctement aux valeurs du tableau statique ?

43voto

Sourav Ghosh Points 54713

Si le tableau statique est automatiquement libéré à la fin de l'exécution, comment pouvons-nous encore accéder correctement aux valeurs du tableau statique ?

Non, ce n'est pas ça. static les variables sont initialisées avant de commencer main() et sa durée de vie est la totalité de l'exécution du programme. Ils peuvent donc être return à partir des fonctions (dans lesquelles ils sont définis) et sont toujours accessibles. Ils ne sont pas local (aux fonctions) qui disparaît lorsque la fonction termine son exécution.

Relié, citant C11 , chapitre §6.2.4

Un objet dont l'identifiant est déclaré sans le spécificateur de classe de stockage. _Thread_local et soit avec un lien externe ou interne, soit avec le spécificateur de classe de stockage static , a une durée de stockage statique. Sa durée de vie correspond à l'exécution complète du programme et sa valeur stockée n'est initialisée qu'une seule fois, avant le démarrage du programme.

En ce qui concerne le portée d'un static à l'intérieur d'une fonction, oui, elle est limitée à la fonction elle-même, comme mentionné dans le chapitre §6.2.1,

[...] Si le déclarateur ou le spécificateur de type qui déclare l'identificateur apparaît à l'intérieur d'un bloc ou dans la liste de déclarations de paramètres dans une définition de fonction, l'identificateur a une portée de bloc, qui se termine à la fin du bloc associé. bloc associé. [...]

Cela signifie, évidemment, que vous ne pouvez pas utiliser le tableau a à l'extérieur de subFunc() comme a n'est pas visible à l'extérieur de subFunc() .

Cependant, lorsque vous return le tableau (le retour d'un tableau entraîne une dégradation du pointeur vers le premier élément du tableau, pour info), car la durée de vie de l'objet static est l'exécution entière du programme, l'accès au pointeur retourné (sûrement, dans les limites) est parfaitement valide et légal.

5 votes

static se comportent un peu différemment des static les globaux : ils sont initialisés non pas au démarrage du programme, mais à la fin de celui-ci. lorsque l'exécution passe pour la première fois leur point d'initialisation .

4 votes

@Quentin Es-tu sûr que c'est aussi le cas pour le C ? Pouvez-vous citer une référence ?

2 votes

Apparemment, j'ai confondu les règles du C et du C++, en effet. C'est ma faute !

21voto

niyasc Points 3825

Les variables statiques continuent d'exister même après la fin du bloc dans lequel elles sont définies. elles sont définies se termine. Ainsi, la valeur d'une variable statique dans une fonction fonction est conservée entre les appels répétés à la même fonction. fonction. La portée des variables statiques automatiques est identique à celle des variables des variables automatiques, c'est-à-dire qu'elle est locale au bloc dans lequel elle est définie, mais le stockage alloué devient permanent pour la durée du programme. durée du programme. Les variables statiques peuvent être initialisées dans leur déclarations ; cependant, les initialisateurs doivent être des expressions constantes, et l'initialisation n'est effectuée qu'une seule fois au moment de la compilation, lorsque la mémoire est l'allocation de mémoire pour la variable statique. - fuente

Les tableaux statiques ou les variables ne seront pas libérés, lorsque le contrôle sort de cette fonction.

Portée d'une variable statique est locale à la fonction dans laquelle elle est déclarée, mais son à vie tout au long du programme.

1 votes

Aujourd'hui même, j'ai entendu quelqu'un dire "peu importe si c'est à l'intérieur d'une fonction, une variable statique est éternelle ".

2 votes

@Agostino Bien sûr, puisque toutes les variables statiques ne sont pas détruites en une seule fois, il est clair que certaines d'entre elles bénéficient d'une plus grande valeur de pour toujours que d'autres :-)

10voto

librik Points 2256

Et pour un tableau statique dans une sous-fonction, le tableau statique sera automatiquement libéré lorsque la sous-fonction appelée sera terminée.

Ce n'est pas vrai. Les tableaux statiques ne sont pas créés lorsque vous entrez dans la fonction, et ils ne sont pas détruits lorsque vous la quittez.

Une variable statique, et les données qu'elle contient, sont en réalité un peu comme une variable globale ! La seule chose qui est locale à la fonction est l'élément nom . (Vous entendrez les gens parler de la "portée" de la variable -- cela signifie "où puis-je utiliser le nom pour m'y référer").

Ainsi, lorsque vous pensez à la durée de vie d'un tableau statique, vous pouvez remplacer mentalement :

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

avec

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;
}

et prétendez ensuite que personne d'autre dans votre programme ne peut toucher cette variable globale.

0 votes

Par ailleurs, certains compilateurs traiteront le premier comme le second, mais en utilisant un nom généré automatiquement comme $STATIC$fd91a2e7$subFunc_a ce qui permet de garantir qu'il n'y a pas de conflit avec quoi que ce soit qui serait valide dans un fichier C [puisque les identificateurs d'utilisateur ne peuvent pas contenir de signes de dollar].

3voto

user3078414 Points 1620

Je me demande pourquoi les tableaux statiques ne doivent pas être libérés ?

  1. Tout ce qui n'est pas alloué par une fonction de gestion de la mémoire (malloc, calloc), telle que int a[5] ne doivent pas être prises en charge explicitement libérant .

  2. Les variables statiques, telles que static int a[5] servent à être accessibles dans la portée locale (ils conservent leurs valeurs entre les appels ultérieurs de la fonction locale). Ils sont créés au moment de la compilation exactement dans ce but, ils ont une durée de vie de programme, il ne serait donc pas logique de les libérer, même si c'était possible, qui n'est pas .

  3. Tout le reste est magistralement expliqué dans d'autres réponses.

2voto

Sanich Points 747

Static variables à l'intérieur d'une fonction, généralement utilisé pour maintenir certaines données dans une portée de la fonction au cours de multiples appels de celle-ci . Ils sont initialisés avant main() et leur durée de vie correspond à l'exécution entière du programme. Donc, cela n'aurait pas de sens s'ils étaient libérés après la sortie de la fonction. Si vous les libérez, vous vous planterez la prochaine fois que vous appellerez la fonction car ils ne seront pas référencés.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X