Frage

Gibt es einen Overhead von variabler Länge Arrays? Könnte die Größe des Arrays über Kommandozeilenparameter zur Laufzeit übergeben werden? Warum ist es eingeführt wird, im Vergleich zu automatischen und dynamisch ein Array Zuweisung?

War es hilfreich?

Lösung

VLA hat einige Overhead (im Vergleich zu "normalen" namens Compile-Zeit-sized Array).

Zum einen hat es die Laufzeitlänge und doch ist die Sprache bietet Ihnen die tatsächliche Größe des Arrays zur Laufzeit (mit sizeof) zu erhalten. Das bedeutet sofort, dass die tatsächliche Größe des Arrays irgendwo gespeichert werden muss. Dies führt in einigen unbedeutenden pro-Array-Speicher-Overhead. da VLAs kann jedoch nur als automatische Objekte deklariert werden, Overhead dieses Gedächtnis ist nicht würde etwas jemals jemand bemerken. Es ist wie eine zusätzliche lokale Variable integralen Typ deklarieren.

Zweitens wird VLA normalerweise auf Stapel reserviert, sondern wegen seiner variablen Größe, im allgemeinen Fall der exakte Position im Speicher wird bei der Kompilierung nicht bekannt. Aus diesem Grunde in der Regel die zugrunde liegende Implementierung hat es als Zeiger auf einen Speicherblock zu implementieren. Dies bringt einige zusätzliche Speicher-Overhead (für den Zeiger), was wiederum völlig unbedeutend für die oben beschriebenen Gründen. Dies führt auch leichte Performance-Overhead, da wir den Zeigerwert zu lesen, um haben die tatsächliche Array zu finden. Dies ist der gleiche Aufwand erhalten Sie, wenn malloc-ed-Arrays Zugriff auf (und nicht mit den genannten Compile-Zeit-sized Arrays erhalten).

Da die Größe des VLA ist eine Laufzeit Integer-Wert, es kann natürlich als Befehlszeilenargument übergeben werden. VLA ist es egal, wo seine Größe kommt.

VLA wurden als Laufzeitgroße Arrays mit geringer Zuteilung / Deallokation Kosten eingeführt. Sie passen zwischen „normalen“ namens Compile-Zeit-sized Arrays (die praktisch Null Zuweisung-Deallokation Kosten, aber feste Größe) und malloc-ed-Arrays (die Laufzeit Größe haben, aber relativ hohe Zuteilungs Deallokation Kosten).

VLA obey [fast] die gleichen Umfang abhängige Lebensdauerregeln als automatisches (d lokal) Objekte, was bedeutet, dass im allgemeinen Fall können sie nicht malloc-ed-Arrays ersetzen. Sie Anwendbarkeit auf Situationen beschränkt ist, wenn Sie eine schnelle Laufzeit Größe Array mit einer typischen automatischen Lebensdauer benötigen.

Andere Tipps

Es gibt einige Laufzeit-Overhead mit variabler Länge Arrays, aber Sie würden ziemlich hart sein müssen arbeiten, sie zu messen. Beachten Sie, dass sizeof(vla) keine Compile-Zeit konstant ist, wenn vla ein Array mit variabler Länge ist.

Die Größe des Arrays kann zur Laufzeit an eine Funktion übergeben werden. Wenn Sie die Größe von einem Befehlszeilenargument und konvertieren, die in eine ganze Zahl nehmen wählen und passieren, dass auf die Funktion zur Laufzeit, soll es so sein -. Es wird funktionieren

Arrays variabler Länge verwendet werden, da die Variablen, auf die richtige Größe automatisch zugeordnet und automatisch freigegeben beim Austritt aus der Funktion. Dies vermeidet über Zuweisung Raum (genügend Platz für die maximal mögliche Größe, wenn Sie hauptsächlich arbeiten mit minimalen Größen Zuteilung) und vermeidet Probleme mit dem Gedächtnis aufzuräumen.

Zusätzlich mit multidimensionalen Arrays AFAIK es verhält sich eher wie Fortran - Sie dynamisch alle Dimensionen konfigurieren können, anstatt für alle mit festen Größen stecken, aber die führende Dimension des Arrays.


Konkrete Anzeichen für eine gewissen Laufzeitaufwand für VLA -. Zumindest mit GCC 4.4.2 auf SPARC (Solaris 10)

Beachten Sie die beiden Dateien unter:

vla.c - mit einem variabler Länge Array

#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 - mit einer festen Länge Array

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

Compilation und Objektdateigrößen

Für Vergleichszwecke wurden die Namen der lokalen Array unterschiedlich sind (vla vs fla) und die Abmessungen auf dem Array sind anders, wenn es deklariert wird -. Andernfalls werden die Dateien sind die gleichen

I zusammengestellt werden:

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

Die Objektdateigrößen sind etwas anders - gemessen sowohl durch ‚ls‘ und ‚Größe‘:

$ 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

Ich habe nicht umfangreiche Tests durchgeführt, um zu sehen, wie viel von dem Kopf befestigt ist, und wie viel ist variabel, aber es gibt Overhead in eine VLA verwendet wird.

  

Ich frage mich nur, wenn es eine Overhead-Arrays variabler Länge zu verwenden?

Nein

  

Kann die Größe des Array könnte zur Laufzeit über die Kommandozeile Argument übergeben werden?

Ja.

  

Warum ist es eingeführt wird, im Vergleich zu automatischen und dynamisch ein Array Zuweisung?

Automatische zugewiesenen erlaubt nur eine feste Größe bei der Kompilierung bekannt.

dynamische Zuweisung (malloc) speichert das Array auf dem Haufen , die einen großen Speicherraum hat, ist aber langsamer zu erreichen.

VLA funktioniert durch das Array Platzierung in der Stapel . Dies macht Verteilung und Zugang extrem schnell, und der Stapel ist in der Regel klein (von wenigen KB), und wenn der VLA den Stapel überschwemmt, es ist nicht von einer unendlichen Rekursion.

sollte es sehr sein wenig Aufwand für VLAs (Allenfalls es in Ergänzung zu dem Stapelzeiger führen soll). Dynamische Zuordnung erfordert manuelle Speicherverwaltung und ist langsamer als Stack-basierte Zuordnung eines VLA und „automatisch“ Deklaration eines Arrays erfordert einen Compiler-Ausdruck für die Feldgröße. Aber denken Sie daran, dass, wenn ein Stapelüberlauf auftritt, wird es nicht definiertes Verhalten verursachen, so halten VLAs relativ klein.

Sie konnten die Größe eines Arrays über ein Befehlszeilenargument übergeben, aber Sie würden den Code, der selbst zu behandeln schreiben.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top