std::array - Keine dynamische Speicherallokation notwendig

Inhaltsverzeichnis[Anzeigen]

std::array verbindet das Beste aus zwei Welten. Zum besitzt es die Größe und Effizienz eines C-Arrays, zum andern bietet es das Interface eines std::vector an.

 

std::array besitzt ein Alleinstellungsmerkmal unter den sequentiellen Container der Standard Template Library. Seine Größe lässt sich nicht dynamisch anpassen. Für seine Initialisierung gelten besondere Regeln.

Die Initialisierung

Bei der Initialisierung eines std::array gelten die Regeln der Aggregat Initialisierung:

  • std::array<int,10> arr: Die 10 Elemente werden nicht initialisiert.
  • std::array<int,10>arr{}. Die 10 Elemente werden auf ihren Default initialisiert.
  • std::array<int,10>arr{1,2,3,4): Die restlichen Elemente werden auf ihren Default initialisiert.

 Als sequentieller Datentyp unterstützt er den Indexzugriff.

Indexzugriff

std::array arr unterstützt den Indexzugriff in drei Formen:

  • arr[n]:Zugriff auf das n-te Element ohne Überprüfung der Array-Grenzen.
  • arr.at(n):Zugriff auf das n-te Element mit Überprüfung der Array-Grenzen. Gegebenenfalls wird eine std::range_error-Ausnahme geworfen.
  • std::get<n>(arr):Zugriff auf das n-te Element mit der Syntax des std::tuple

std::get<n>(arr) unterstreicht die Verwandtschaft vom std::array mit dem std::tuple. Während std::array ein homogener Container fester Länge ist, ist std::tuple ein heterogener Container fester Länge.

Ich habe behauptet, das C++-Array ist so Speicher effizient wie das C+-Array. Den Beweis bin ich aber schuldig geblieben.

Speichereffizienz

In meinem kleinen Programm stelle ich die Speichereffizienz eines C-Arrays, eines C++-Arrays und eines std::vector gegenüber.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
// sizeof.cpp

#include <iostream>
#include <array>
#include <vector>
 
 
int main(){
  
  std::cout << std::endl;
  
  std::cout << "sizeof(int)= " << sizeof(int) << std::endl;
  
  std::cout << std::endl;
  
  int cArr[10]= {1,2,3,4,5,6,7,8,9,10};
  
  std::array<int,10> cppArr={1,2,3,4,5,6,7,8,9,10};
  
  std::vector<int> cppVec={1,2,3,4,5,6,7,8,9,10};
  
  std::cout << "sizeof(cArr)= " << sizeof(cArr) << std::endl;  
  
  std::cout << "sizeof(cppArr)= " << sizeof(cppArr) << std::endl;
  
  std::cout << "sizeof(cppVec) = "   << sizeof(cppVec) + sizeof(int)*cppVec.capacity() << std::endl;
  std::cout << "               = sizeof(cppVec): " << sizeof(cppVec) << std::endl;
  std::cout << "               + sizeof(int)* cppVec.capacity(): "   << sizeof(int)* cppVec.capacity() << std::endl;

  std::cout << std::endl;
  
}

 

Die Zahlen sprechen eine eindeutige Sprache.

sizeof

Sowohl das C-Array (Zele 22) als auch das C++-Array (Zeile 24) benötigen 40 Byte. Das entspricht der Größe sizeof(int)*10. Im Gegensatz dazu benötigt der std::vector 24 zusätzliche Bytes (Zeile 27) um seine Daten auf dem freien Speicher zu verwalten. cppVec.capacity() ist die Anzahl der Elemente, die der std::vector cppVec besitzen kann, ohne dass er neuen Speicher anfordern muss. Die Details zum Speichermanagement von std::vector und std::string habe ich in dem Artikel Automatisches Speichermanagement mit Containern detailiiert vorgestellt.

Um das Bild abzurunden, noch eine kleine Anwendung mit std::array.

std::array im Einsatz

Der wahre Mehrwert von std::array gegenüber dem C-Array ist es, dass sich die Algorithmen der Standard Template Library auf dem  std::array anwenden lassen.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
// array.cpp

#include <algorithm>
#include <array>
#include <iostream>

int main(){

  std::cout << std::endl;

  // output the array
  std::array <int,8> array1{1,2,3,4,5,6,7,8};
  std::for_each( array1.begin(),array1.end(),[](int v){std::cout << v << " ";});

  std::cout << std::endl;

  // calculate the sum of the array by using a global variable
  int sum = 0;
  std::for_each(array1.begin(), array1.end(),[&sum](int v) { sum += v; });
  std::cout << "sum of array{1,2,3,4,5,6,7,8}: " << sum << std::endl;

  // change each array element to the second power
  std::for_each(array1.begin(), array1.end(),[](int& v) { v=v*v; });
  std::for_each( array1.begin(),array1.end(),[](int v){std::cout << v << " ";});
  std::cout << std::endl;

  std::cout << std::endl;

}

 

So lässt sich array1 in Zeile 13 mit der Lambda-Funktion und dem for_each-Algorithmus ausgeben. Im Gegensatz dazu bindet die Lambda-Funktion die Summationsvariable sum in Zeile 19. Mit ihrer Hilfe werden die Elemente des std:.array zusammen addiert. Die Lambda-Funktion in Zeile 23 nimmt ihr Argument als Referenz an und kann daher jedes Element des std::array auf sein Quadrat abbilden. Alles nichts Besonderes, wäre der zugrundeliegende Container kein std::array.

Zum Abschluss noch die Ausgabe des Programms.

array

Wie geht's weiter?

Dieser Artikel war kurz und schmerzlos. Im nächsten Artikel schaue ich mir eines der prominentesten Feature von C++11 an, die Move-Semantik.

 

 

 

 

 

 

 

 

title page smalltitle page small Go to Leanpub/cpplibrary "What every professional C++ programmer should know about the C++ standard library".   Hole dir dein E-Book. Unterstütze meinen Blog.

 

 

Kommentare   

0 #1 Marco 2016-06-07 06:36
Hallo Rainer, beim Versuch sich für den Newsletter anzumelden kommt in Chrome (auf PC, Windows 7) leider folgende Fehlermeldung un ddie Anmeldung schlägt fehl:
The form could not be submitted TypeError: Cannot read property 'elements' of undefined
Zitieren
0 #2 Rainer Grimm 2016-06-08 19:34
zitiere Marco:
Hallo Rainer, beim Versuch sich für den Newsletter anzumelden kommt in Chrome (auf PC, Windows 7) leider folgende Fehlermeldung un ddie Anmeldung schlägt fehl:
The form could not be submitted TypeError: Cannot read property 'elements' of undefined

Vielen Dank, Marco. Ich kann das Problem (10 Tage später) nicht reproduzieren. In meiner Virtualbox habe ich mich mit Chrome auf Windows zweimal an den Newsletter anmelden können.
Zitieren

Kommentar schreiben


Modernes C++

Abonniere den Newsletter

Inklusive zwei Artikel meines Buchs
Introduction und Multithreading

Beiträge-Archiv

Sourcecode

Neuste Kommentare