Question

Y at-il d'utiliser des tableaux généraux de longueur variable? la taille du tableau pourrait être transmis par argument de ligne de commande lors de l'exécution? Pourquoi est-il introduit, par rapport à automatique et allocation dynamique un tableau?

Était-ce utile?

La solution

VLA a une certaine surcharge (par rapport à « ordinaire » du nom de tableau à la compilation de la taille).

Tout d'abord, il a une longueur d'exécution et encore la langue que vous fournit des moyens pour obtenir la taille réelle du tableau à l'exécution (en utilisant sizeof). Cela signifie immédiatement que la taille réelle du tableau doit être stocké quelque part. Il en résulte une surcharge de mémoire insignifiante par-tableau. Cependant, étant donné que VLA ne peut être déclarée comme des objets automatiques, cette surcharge de mémoire est pas quelque chose qui que ce soit aurait jamais remarqué. Il est tout comme la déclaration d'une variable locale supplémentaire de type intégral.

En second lieu, VLA est normalement alloué sur la pile, mais en raison de sa taille variable, en cas général son emplacement exact dans la mémoire n'est pas connue au moment de la compilation. Pour cette raison, la mise en œuvre sous-jacente a généralement de mettre en œuvre comme un pointeur sur un bloc de mémoire. Cela introduit une surcharge de la mémoire supplémentaire (pour le pointeur), ce qui est encore tout à fait insignifiante pour les raisons décrites ci-dessus. Cela introduit aussi la performance légère surcharge, puisque nous devons lire la valeur de pointeur pour trouver le véritable tableau. C'est la même tête que vous obtenez lorsque l'accès aux tableaux malloc-ed (et ne sont pas avec les tableaux de la compilation de taille nommées).

Etant donné que la taille de la VLA est une valeur entière de l'exécution, il peut, bien entendu, être passé comme un argument de ligne de commande. VLA ne se soucie pas où sa taille vient.

VLA ont été introduites sous forme de tableaux à la gestion du temps de taille avec une faible allocation / coût de désaffectation. Ils correspondent entre « ordinaires » nommés à la compilation de la taille des tableaux (qui ont coût pratiquement nul allocation désaffectation, mais la taille fixe) et les tableaux malloc-ed (qui ont la taille de l'exécution, mais relativement élevé l'allocation des coûts-désallocation).

VLA obéir [presque] les mêmes règles de vie en fonction de la portée comme des objets automatiques (i.e. locaux), ce qui signifie qu'en cas général, ils ne peuvent pas remplacer les tableaux malloc-ed. Ils applicabilité est limitée aux situations où vous avez besoin d'un tableau de taille d'exécution rapide avec une durée de vie typique automatique.

Autres conseils

Il y a certains frais généraux d'exécution avec des tableaux de longueur variable, mais vous devez travailler assez dur pour le mesurer. Notez que sizeof(vla) n'est pas une constante de compilation si vla est un tableau de longueur variable.

La taille de la matrice peut être transmis à une fonction au moment de l'exécution. Si vous choisissez de prendre la taille d'un argument de ligne de commande et la convertir en un entier et passer à la fonction que lors de l'exécution, alors il -. Il travaillera

tableaux de longueur variable sont utilisés parce que les variables sont attribués automatiquement à la taille correcte et libérés automatiquement à la sortie de la fonction. Cela évite trop l'allocation d'espace (allocation suffisamment d'espace pour la taille maximale possible lorsque vous travaillez avec la plupart du temps tailles minimales), et évite des problèmes de mémoire nettoyer.

En outre, avec des tableaux multidimensionnels, AFAIK il se comporte plus comme Fortran - vous pouvez configurer dynamiquement toutes les dimensions, plutôt que d'être coincé avec des tailles fixes pour tous, mais la dimension principale du tableau.


Des preuves concrètes de certains frais généraux d'exécution pour VLA -. Au moins avec GCC 4.4.2 sur SPARC (Solaris 10)

Considérons les deux fichiers ci-dessous:

vla.c - en utilisant un tableau de longueur variable

#include <assert.h>
#include <stddef.h>
extern size_t identity_matrix(int n, int m);

size_t identity_matrix(int n, int m)
{
    int vla[n][m];
    int i, j;
    assert(n > 0 && n <= 32);
    assert(m > 0 && m <= 32);
    for (i = 0; i < n; i++)
    {
        for (j = 0; j < m; j++)
        {
            vla[i][j] = 0;
        }
        vla[i][i] = 1;
    }
    return(sizeof(vla));
}

fla.c - en utilisant un tableau de longueur fixe

#include <assert.h>
#include <stddef.h>
extern size_t identity_matrix(int n, int m);

size_t identity_matrix(int n, int m)
{
    int fla[32][32];
    int i, j;
    assert(n > 0 && n <= 32);
    assert(m > 0 && m <= 32);
    for (i = 0; i < n; i++)
    {
        for (j = 0; j < m; j++)
        {
            fla[i][j] = 0;
        }
        fla[i][i] = 1;
    }
    return(sizeof(fla));
}

taille des fichiers de compilation et d'objets

A titre de comparaison, le nom du tableau local sont différents (vla vs fla), et les dimensions du tableau sont différentes quand elle est déclarée -. Sinon, les fichiers sont les mêmes

Je compilé à l'aide:

$ gcc -O2 -c -std=c99 fla.c vla.c

La taille des fichiers d'objets sont quelque peu différentes - telle que mesurée à la fois par « ls » et par « taille »:

$ ls -l fla.o vla.o
-rw-r--r--   1 jleffler rd          1036 Jan  9 12:13 fla.o
-rw-r--r--   1 jleffler rd          1176 Jan  9 12:13 vla.o
$ size fla.o vla.o
fla.o: 530 + 0 + 0 = 530
vla.o: 670 + 0 + 0 = 670

Je ne l'ai pas fait des tests approfondis pour voir à quel point la tête est fixe et combien est variable, mais il est en tête dans l'utilisation d'un VLA.

  

Je me demande s'il y a une surcharge d'utiliser des tableaux de longueur variable?

Non

  

la taille du tableau peut être transmis par l'intermédiaire pourrait argument de ligne de commande lors de l'exécution?

Oui.

  

Pourquoi est-il introduit, par rapport à automatique et allocation dynamique un tableau?

automatique ne permet AFFECTÉ une taille fixe connue au moment de la compilation.

allocation dynamique (malloc) va stocker le tableau sur la tas , qui a un grand espace mémoire, mais est plus lent à accéder.

VLA fonctionne en plaçant la matrice dans la pile . Cela rend l'allocation et l'accès extrêmement rapide, mais la pile est généralement faible (de quelques KB), et lorsque le VLA débordait la pile, il est impossible de distinguer une récursion infinie.

Il devrait y avoir très peu de frais généraux pour VLA (au plus, il devrait se traduire par un ajout au pointeur de la pile). L'allocation dynamique nécessite la gestion de la mémoire manuelle et est plus lente que l'allocation basée sur la pile d'un VLA, et la déclaration « automatique » d'un tableau nécessite une expression de compilation pour la taille du tableau. Cependant, gardez à l'esprit que si un débordement de pile se produit, il provoque un comportement non défini, donc gardez VLA relativement faible.

Vous pouvez passer la taille d'un tableau par un argument de ligne de commande, mais vous devez écrire le code pour gérer vous-même.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top