Tableau statique vs tableau dynamique en C ++

91

Quelle est la différence entre un tableau statique et un tableau dynamique en C ++?

Je dois faire un devoir pour ma classe et il est dit de ne pas utiliser de tableaux statiques, seulement des tableaux dynamiques. J'ai regardé dans le livre et en ligne, mais je ne semble pas comprendre.

Je pensais que la statique avait été créée au moment de la compilation et dynamique au moment de l'exécution, mais je me trompe peut-être avec l'allocation de mémoire.

Pouvez-vous expliquer la différence entre un tableau statique et un tableau dynamique en C ++?

user69514
la source
1
La statique n'est pas le contraire de la dynamique. Soit le livre que vous utilisez est terrible, soit vous le sortez de son contexte. Je vais ajouter une nouvelle réponse ci-dessous pour clarifier cela avec un peu de chance.
Joshua Clayton
3
Voir le diagramme dans cette question: stackoverflow.com/a/11698458/1143274 Les tableaux statiques ne sont pas alloués sur la pile ou le tas.
Evgeni Sergeev
* tableau fixe vs tableau dynamique
csguy

Réponses:

102

Les baies locales sont créées sur la pile et ont une durée de stockage automatique - vous n'avez pas besoin de gérer manuellement la mémoire, mais elles sont détruites lorsque la fonction dans laquelle elles se trouvent se termine. Ils ont forcément une taille fixe:

int foo[10];

Les tableaux créés avec operator new[]ont une durée de stockage dynamique et sont stockés sur le tas (techniquement le «magasin gratuit»). Ils peuvent avoir n'importe quelle taille, mais vous devez les allouer et les libérer vous-même car ils ne font pas partie du cadre de la pile:

int* foo = new int[10];
delete[] foo;
Michael Mrozek
la source
18
C'est correct, mais seulement pour illustrer comment cela fonctionne. Veuillez ne pas faire cela dans du vrai code mais utilisez plutôt un std :: vector.
Eddy Pronk
23
@Eddy: Cela dépend de la situation pour savoir si un vecteur est nécessaire
Casebash
6
@Casebash: Dans quelle situation préféreriez-vous un tableau? "Vous devriez toujours préférer utiliser des vecteurs ou des deques au lieu de tableaux." - Herb Sutter (C ++ plus exceptionnel)
Eddy Pronk
16
@EddyPronk Pour des raisons de fragmentation de la mémoire, on peut utiliser un tableau fixe comme une sorte de pool. Tous les cas ne nécessitent pas le tas, il y a des avantages particuliers à utiliser des tableaux basés sur la pile. Vous traitez le std :: vector comme un marteau d'or, un anti-motif courant.
void.pointer
4
@EddyPronk: Je suis presque sûr que Herb Sutter voulait dire des tableaux dynamiques, comme ceux int* foo = new int[N]que vous avez pour deletevous-même et donc soyez prudent en présence d'exception. Les tableaux statiques n'ont pas ces problèmes.
Alexander Malakhov
31

static est un mot-clé en C et C ++, donc plutôt qu'un terme descriptif général, static a une signification très spécifique lorsqu'il est appliqué à une variable ou un tableau. Pour aggraver la confusion, il a trois significations distinctes dans des contextes distincts. Pour cette raison, un tableau statique peut être fixe ou dynamique.

Laissez-moi expliquer:

Le premier est spécifique au C ++:

  • Un membre de classe statique est une valeur qui n'est pas instanciée avec le constructeur ou supprimée avec le destructeur. Cela signifie que le membre doit être initialisé et maintenu d'une autre manière. Les membres statiques peuvent être des pointeurs initialisés à null, puis alloués la première fois qu'un constructeur est appelé. (Oui, ce serait statique et dynamique)

Deux sont hérités de C:

  • dans une fonction, une variable statique est une variable dont l'emplacement mémoire est conservé entre les appels de fonction. Il est statique en ce sens qu'il n'est initialisé qu'une seule fois et conserve sa valeur entre les appels de fonction (l'utilisation de la statique rend une fonction non réentrante, c'est-à-dire non threadsafe)

  • les variables statiques déclarées en dehors des fonctions sont des variables globales qui ne sont accessibles qu'à partir du même module (fichier de code source avec tout autre # include)

La question (je pense) que vous vouliez poser est de savoir quelle est la différence entre les tableaux dynamiques et les tableaux fixes ou à la compilation. C'est une question plus simple, les tableaux au moment de la compilation sont déterminés à l'avance (lorsque le programme est compilé) et font partie d'un cadre de pile de fonctions. Ils sont alloués avant l'exécution de la fonction principale. les tableaux dynamiques sont alloués à l'exécution avec le mot-clé "new" (ou la famille malloc de C) et leur taille n'est pas connue à l'avance. les allocations dynamiques ne sont pas automatiquement nettoyées jusqu'à ce que le programme cesse de s'exécuter.

Joshua Clayton
la source
4
+1, votre réponse est la plus exacte et la plus précise et aurait dû recevoir plus de votes.
Z boson
Si vous déclarez la taille du tableau avec l' new[]opérateur, comment se fait-il que la taille ne soit pas connue avant l'exécution? ieint* p = new int[10]
wulfgarpro
"Ils sont alloués avant l'exécution de la fonction principale." Pourquoi allouer les variables de pile avant que le bloc concerné ne soit entré?
AlwaysLearning
Les variables de pile (généralement des variables locales dans une fonction) ont une taille et une position prédéfinies dans un cadre de pile et la pile entière est allouée avant l'exécution de la fonction principale, @AlwaysLearning. Lors de la saisie d'un cadre de pile via un appel de fonction, le pointeur de pile est mis à jour, mais le nouveau cadre de pile se trouve dans la pile. Plus aucune pile n'est allouée. En fait, trop de variables (un tableau géant par exemple) ou trop d'appels de fonctions ouverts en même temps entraîne un débordement de pile, pour lequel ce site est nommé.
Joshua Clayton
@JoshuaClayton Je pense que cela ne peut pas être correct. Comment pouvez-vous allouer les cadres de pile (notez le pluriel) pour une fonction récursive lorsque vous ne savez pas combien de fois elle sera saisie?
AlwaysLearning
11

Je pense que la sémantique utilisée dans votre classe prête à confusion. Ce que l'on entend probablement par «statique» est simplement «taille constante», et ce que l'on entend probablement par «dynamique» est «taille variable». Dans ce cas, un tableau de taille constante pourrait ressembler à ceci:

int x[10];

et un "dynamique" serait simplement n'importe quel type de structure qui permet d'augmenter ou de diminuer le stockage sous-jacent au moment de l'exécution. La plupart du temps, la std::vectorclasse de la bibliothèque standard C ++ suffit. Utilisez-le comme ceci:

std::vector<int> x(10); // this starts with 10 elements, but the vector can be resized.

std::vectora operator[]défini, vous pouvez donc l'utiliser avec la même sémantique qu'un tableau.

Ben Collins
la source
1
Je pense qu'il est assez clair que par "tableau dynamique", ils signifient simplement un tableau alloué dynamiquement (c'est-à-dire un tableau dans lequel la taille peut être spécifiée dynamiquement, au moment de l'exécution). J'aimenew int[10]
jalf
@jalf: J'étais plus préoccupé par le terme «statique». Je préfère appeler un "tableau dynamique" un tableau de taille allouée ou variable par souci de cohérence.
Ben Collins
Bon point car un tableau statique pourrait être automatique et implémenté sur la pile ou être global et implémenté dans une section de données. Les deux sont statiques mais en interne le code qui y accède peut être très différent.
Z boson
9

Les tableaux statiques reçoivent de la mémoire au moment de la compilation et la mémoire est allouée sur la pile. Alors que les tableaux dynamiques se voient allouer de la mémoire au moment de l'exécution et que la mémoire est allouée à partir du tas.

int arr[] = { 1, 3, 4 }; // static integer array.   
int* arr = new int[3]; // dynamic integer array.
Jagannath
la source
4
Un tableau global est un tableau statique et il est implémenté dans une section de données et non à partir de la pile.
Z boson
8

Il est important d'avoir des définitions claires de ce que signifient les termes. Malheureusement, il semble y avoir plusieurs définitions de ce que signifient les tableaux statiques et dynamiques.

Les variables statiques sont des variables définies à l' aide de l'allocation de mémoire statique . Il s'agit d'un concept général indépendant de C / C ++. En C / C ++, nous pouvons créer des variables statiques avec une portée globale, fichier ou locale comme ceci:

int x[10]; //static array with global scope
static int y[10]; //static array with file scope
foo() {
    static int z[10]; //static array with local scope

Les variables automatiques sont généralement implémentées à l'aide d' une allocation de mémoire basée sur la pile . Un tableau automatique peut être créé en C / C ++ comme ceci:

foo() {
    int w[10]; //automatic array

Ce que ces tableaux, x, y, zet wont en commun, c'est que la taille de chacun d'eux est fixe et définie au moment de la compilation.

L'une des raisons pour lesquelles il est important de comprendre la distinction entre un tableau automatique et un tableau statique est que le stockage statique est généralement implémenté dans la section de données (ou section BSS ) d'un fichier objet et le compilateur peut utiliser des adresses absolues pour accéder aux tableaux. ce qui est impossible avec le stockage basé sur la pile.

Ce que l'on entend généralement par tableau dynamique n'est pas un tableau redimensionnable, mais implémenté à l'aide d' une allocation de mémoire dynamique avec une taille fixe déterminée au moment de l'exécution. En C ++, cela se fait à l'aide de l' newopérateur .

foo() {
   int *d = new int[n]; //dynamically allocated array with size n     

Mais il est possible de créer un tableau automatique avec une taille de correctifs définie au moment de l'exécution en utilisant alloca:

foo() {
    int *s = (int*)alloca(n*sizeof(int))

Pour un vrai tableau dynamique, il faut utiliser quelque chose comme std::vectoren C ++ (ou un tableau de longueur variable en C ).

Que signifiait la mission dans la question du PO? Je pense qu'il est clair que ce qui était recherché n'était pas un tableau statique ou automatique, mais un tableau qui utilisait l'allocation de mémoire dynamique à l'aide de l' newopérateur ou un tableau de taille non fixe utilisant par exemple std::vector.

Boson Z
la source
3

Je pense que dans ce contexte, cela signifie qu'il est statique dans le sens où la taille est fixe. Utilisez std :: vector. Il a une fonction resize ().

Eddy Pronk
la source
2

Vous pouvez avoir un pseudo tableau dynamique dont la taille est définie par l'utilisateur lors de l'exécution, mais est ensuite corrigée par la suite.

int size;
cin >> size;
int dynamicArray[size];
Joshua Oliphant
la source
Ne fait pas partie du C ++ standard (en C99 et en tant qu'extension de compilateur pour gcc).
crashmstr
1

Tableau statique :

  1. Les tableaux statiques reçoivent de la mémoire au moment de la compilation.
  2. La taille est fixe.
  3. Situé dans l'espace mémoire de la pile.
  4. Par exemple. : tableau int [10]; // tableau de taille 10

Tableau dynamique:

  1. La mémoire est allouée au moment de l'exécution.
  2. La taille n'est pas fixe.
  3. Situé dans l'espace mémoire du tas.
  4. Par exemple. : int * array = new int [10];
Tejashree Kudale
la source
0

Oui, le tableau statique est créé au moment de la compilation, alors que le tableau dynamique est créé au moment de l'exécution. Là où la différence concerne leurs emplacements de mémoire, les statiques sont situées sur la pile et les dynamiques sont créées sur le tas. Tout ce qui se trouve sur le tas a besoin de la gestion de la mémoire jusqu'à ce que et à moins qu'un garbage collector comme dans le cas du framework .net soit présent, sinon il y a un risque de fuite de mémoire.

Aadil Imran
la source
0

Tableau statique: efficacité. Aucune allocation dynamique ou désallocation n'est requise.

Les tableaux déclarés en C, C ++ dans la fonction incluant le modificateur statique sont statiques. Exemple: static int foo [5];

Khuê Phạm
la source
1
@admdrew, c'est vrai mais la question n'a jamais été bien répondue. La meilleure réponse est la réponse de Joshua Clayton, mais je pense qu'une meilleure réponse est celle-ci: stackoverflow.com/questions/17775066/…
Z boson
@Zboson Bon à savoir, merci. Heh et moi venons de réaliser que j'ai fait ce commentaire il y a presque un an maintenant.
admdrew
-3

arrary statique meens avec donner des éléments à côté du tableau

arrary dynamique meens sans donner sur les éléments à côté du tableau

exemple:

     char a[10]; //static array
       char a[];  //dynamic array
Karthik
la source
Je pense qu'il a dit correct. Lorsque vous donnez une longueur exacte au tableau, c'est un tableau statique et lorsque vous ne donnez pas de longueur, c'est un tableau dynamique. mais comme il ne sait pas écrire l'anglais, c'est pourquoi les gens notent cette réponse.
muhammad tayyab