Variable Length Array
Ein Variable Length Array (VLA) ist ein Datentyp der Programmiersprache C. Es handelt sich um ein Feld (englisch Array), dessen Größe erst zur Laufzeit, d. h. variabel, festgelegt wird.
Funktionsweise und Anwendung
Im Gegensatz zum klassischen Vektor, dessen Größe zum Zeitpunkt der Übersetzung festgelegt wird,[1] führt der C99-Standard das Konzept variabler Array-Größen ein. Bei der Definition eines Feldes kann dessen Größe durch einen beliebigen ganzzahligen Ausdruck bestimmt werden.
- Beispiel Vektor und VLA
void foo(unsigned int len) {
int vector[3] = { 14, 4, 7 }; /* initialisiertes Feld fixer Größe */
int vla[len]; /* VLA entsprechend dem Parameter len */
...
}
Dabei ist zu beachten, dass VLAs nicht initialisiert werden können (Einschränkung in den C-Standards, vgl. §6.7.8 respektive §6.7.9)[2][3] und die Größe nur einmalig bei der Definition festgelegt werden kann. Darüber hinaus können VLAs nur innerhalb von Funktionen angelegt werden. Außerhalb von Funktionen müssen Feldgrößen auch in C99 zum Zeitpunkt der Übersetzung bekannt sein. Der Gültigkeitsbereich eines VLAs beginnt wie bei allen lokalen Variablen mit dessen Definition und umfasst den umschließenden Block.
Ein großer Vorteil von VLAs ist, dass für temporäre Felder der Aufruf von malloc()
und free()
wegfällt; der Compiler übernimmt die Anforderung und Freigabe des erforderlichen Speichers.[4] Da in der Regel VLAs auf dem Stack und nicht auf dem Heap angelegt werden, ist die Speicheranforderung auch erheblich effizienter.[5] Außerdem kann auf feste Array-Größen, die häufig Ursache für Softwarefehler sind, verzichtet werden.[6]
Beispiel
Das folgende Beispiel zeigt eine typische Anwendung von VLAs.
- Beispiel Zeichenfolge eines beliebig langen Strings umkehren
#include <stdio.h>
#include <string.h>
char* reverse_string(char* in_out){
unsigned int len = strlen(in_out);
char tmp[len + 1]; // VLA für String und Nullterminierung
strcpy(tmp, in_out);
for (int i = 0; i < len; i++)
in_out[i] = tmp[len - i - 1];
return in_out;
}
int main(void) {
char tmp[] = "Hallo";
printf("%s\n", reverse_string(tmp));
return 0;
}
Die Funktion reverse_string()
verwendet die lokale Variable tmp
als VLA; dieses nimmt den übergebenen String auf. Im Anschluss wird der String in umgekehrter Reihenfolge wieder in den Ein-/Ausgabeparameter in_out
zurückgeschrieben.
Selbstverständlich lassen sich auch mehrdimensionale VLAs generieren, wie das Beispiel aus dem C11-Standard zeigt int a[n][6][m];
[3]
Auswirkungen
Der Operator sizeof
muss bei VLAs zur Laufzeit ausgewertet werden, d. h. für jedes VLA muss Meta-Information zur Laufzeit generiert werden.[5] Die Definition von VLAs darf nicht übersprungen werden, hier schränken die C-Standards die Benutzung von goto
ein.[2][3]
Im Gegensatz zu C99 ist die Implementierung von VLAs bei C11-konformen Compilern freigestellt. Die Verfügbarkeit kann über das Define __STDC_NO_VLA__
abgefragt werden, das den Integerwert 1 aufweist, sofern VLAs nicht unterstützt werden.[3]
Abgrenzung zu anderen Programmiersprachen
VLAs sind C-spezifisch und werden nicht vom C++-Standard übernommen. C++ bietet Container-Klassen, die variable Felder ermöglichen. Die Programmiersprachen APL und Perl unterstützen beispielsweise Felder, deren Größe zur Laufzeit verändert werden kann.[5] Arrays in Java haben eine feste Größe. Da sie dynamisch angelegt werden, können wie bei VLAs die Größen zur Laufzeit festgelegt werden.
Einzelnachweise
- Kernighan/Ritchie: Programmieren in C - Mit dem C-Referenz Manual in deutscher Sprache, Hanser 1990, 2. Auflage
- ISO/IEC9899-1999 Programming Languages -- C
- ISO/IEC9899-2011 Programming Languages -- C
- Randy Meyers: The New C: Why Variable Length Arrays?, Dr. Dobb's, 1. October 2001, Online: http://www.drdobbs.com/the-new-cwhy-variable-length-arrays/184401444 . Abgerufen am 12. August 2014
- Derek M. Jones: The New C Standard - An Economic and Cultural Commentary, Addison-Wesley Professional 2008, auch Online: http://www.coding-guidelines.com/cbook/cbook1_2.pdf . Abgerufen am 12. August 2014
- Webseite des CERT Secure Coding Standard STR35-C. Abgerufen am 14. Februar 2016