Provided by: manpages-de-dev_4.13-4_all bug

BEZEICHNUNG

       hcreate, hdestroy, hsearch, hcreate_r, hdestroy_r, hsearch_r - Verwaltung von Hash-Tabellen

ÜBERSICHT

       #include <search.h>

       int hcreate(size_t nel);

       ENTRY *hsearch(ENTRY item, ACTION action);

       void hdestroy(void);

       #define _GNU_SOURCE         /* siehe feature_test_macros(7) */
       #include <search.h>

       int hcreate_r(size_t nel, struct hsearch_data *htab);

       int hsearch_r(ENTRY item, ACTION action, ENTRY **retval,
                     struct hsearch_data *htab);

       void hdestroy_r(struct hsearch_data *htab);

BESCHREIBUNG

       Die  drei  Funktionen  hcreate(),  hsearch()  und  hdestroy() ermöglichen dem Aufrufer die Erstellung und
       Verwaltung einer Hash-Suchtabelle. Deren Einträge sind Paare aus einem Schlüssel (eine Zeichenkette)  und
       zugeordneten Daten. Mit diesen Funktionen kann immer nur eine Hash-Tabelle genutzt werden.

       Die drei Funktionen hcreate_r(), hsearch_r(), hdestroy_r() sind ablaufinvariante Funktionen, die überdies
       Programmen  ermöglichen,  mit mehreren Hash-Tabellen gleichzeitig zu arbeiten. Das letzte Argument, htab,
       zeigt auf eine Struktur mit der Beschreibung der Hash-Tabelle,  die  die  Funktion  verwenden  soll.  Der
       Programmierer  sollte  diese  Struktur  als  »undurchsichtig«  behandeln (d.h. er sollte nicht versuchen,
       direkt auf Felder der Struktur zuzugreifen oder zu verändern).

       Zuerst muss mittels hcreate() eine Hash-Tabelle erzeugt werden. Das Argument nel gibt die Maximalzahl der
       Einträge in der Tabelle an. (Dieses Maximum kann in der Folge nicht geändert werden, wählen Sie  es  also
       mit  Bedacht.)  Es  ist  möglich,  dass  die  Implementierung  diesen  Wert  nach  oben  anpasst,  um die
       Leistungsfähigkeit der resultierenden Hash-Tabelle zu verbessern.

       Die Funktion hcreate_r() erledigt die gleiche Aufgabe wie hcreate(), tut das aber für  die  Tabelle,  die
       durch  die  Struktur *htab beschrieben wird. Vor dem ersten Aufruf von hcreate_r() muss die Struktur htab
       mit Nullen initialisiert werden.

       Die Funktion hdestroy() gibt den Speicher frei, den die von hcreate() erzeugte Hash-Tabelle  beansprucht.
       Nach dem Aufruf von hdestroy() kann mittels hcreate() eine neue Hash-Tabelle erzeugt werden. Die Funktion
       hdestroy_r()  erledigt  die  analoge  Aufgabe  für  die  durch *htab beschriebene Hash-Tabelle, die zuvor
       mittels hcreate_r() erzeugt wurde.

       Die Funktion hsearch() durchsucht die Hash-Tabelle nach einem Eintrag mit dem gleichen Schlüssel wie item
       (wobei »der gleiche« mittels strcmp(3) bestimmt wird) und gibt bei Erfolg einen Zeiger auf diesen Eintrag
       zurück.

       Das Argument item ist vom Typ ENTRY, der in <search.h> wie folgt definiert wird:

           typedef struct entry {
               char *key;
               void *data;
           } ENTRY;

       Das Feld key zeigt auf eine null-terminierte Zeichenkette, die als Suchschlüssel  dient.  Das  Feld  data
       zeigt auf dem Schlüssel zugeordnete Daten.

       Das Argument action bestimmt, was hsearch() nach einer erfolglosen Suche unternimmt. Dieses Argument muss
       einen  von  zwei  Werten  annehmen:  für den Wert ENTER soll eine Kopie von item in die Tabelle eingefügt
       werden (und ein Zeiger auf den neuen Eintrag in der Hash-Tabelle als Ergebnis der Funktion  zurückgegeben
       werden);  FIND  bedeutet, dass NULL zurückgegeben werden sollte. (Falls action gleich FIND ist, wird data
       ignoriert.)

       Die Funktion hsearch_r() arbeitet wie hsearch(), aber mit der durch *htab beschriebenen Hash-Tabelle. Der
       Unterschied zwischen hsearch_r() und hsearch() ist, das der Zeiger auf den gefundenen Eintrag in  *retval
       zurückgegeben wird und nicht als Funktionsergebnis.

RÜCKGABEWERT

       hcreate()  und hcreate_r() geben bei Erfolg einen Wert ungleich null zurück; im Fehlerfall 0, wobei errno
       auf die Ursache des Fehlers gesetzt wird.

       Bei Erfolg gibt hsearch() einen Zeiger auf einen Eintrag in der Hash-Tabelle  zurück.  Bei  einem  Fehler
       gibt hsearch() NULL zurück. Fehler treten auf, wenn die gewünschte action ENTER und die Hash-Tabelle voll
       ist  oder wenn die action FIND ist und item nicht in der Hash-Tabelle gefunden werden kann. Im Fehlerfall
       setzen diese zwei Funktionen errno, um die Ursache des Fehlers anzuzeigen.

FEHLER

       hcreate_r() und hdestroy_r() können aus den folgenden Gründen fehlschlagen:

       EINVAL htab ist NULL.

       hsearch() und hsearch_r()  können aus den folgenden Gründen fehlschlagen:

       ENOMEM Die action war ENTER, key wurde nicht in der Tabelle gefunden und es war nicht  ausreichend  Platz
              für einen neuen Eintrag vorhanden.

       ESRCH  Die action war FIND und key wurde nicht in der Tabelle gefunden.

       POSIX.1 beschreibt nur den Fehler ENOMEM.

ATTRIBUTE

       Siehe attributes(7) für eine Erläuterung der in diesem Abschnitt verwandten Ausdrücke.
       ┌───────────────────────────┬───────────────────────┬────────────────────────┐
       │ SchnittstelleAttributWert                   │
       ├───────────────────────────┼───────────────────────┼────────────────────────┤
       │ hcreate(), hsearch(),     │ Multithread-Fähigkeit │ MT-Unsafe race:hsearch │
       │ hdestroy()                │                       │                        │
       ├───────────────────────────┼───────────────────────┼────────────────────────┤
       │ hcreate_r(), hsearch_r(), │ Multithread-Fähigkeit │ MT-Safe race:htab      │
       │ hdestroy_r()              │                       │                        │
       └───────────────────────────┴───────────────────────┴────────────────────────┘

KONFORM ZU

       Die  Funktionen  hcreate(),  hsearch()  und  hdestroy()  stammen  aus SVr4 und werden in POSIX.1-2001 und
       POSIX.1-2008 beschrieben.

       Die Funktionen hcreate_r(), hsearch_r() und hdestroy_r() sind GNU-Erweiterungen.

ANMERKUNGEN

       Implementierungen von Hash-Tabellen sind in der Regel effizienter, wenn die  Tabelle  ausreichend  freien
       Raum  bereitstellt,  um  Kollisionen  zu reduzieren. Typischerweise bedeutet das, dass nel mindestens 25%
       größer als sein sollte als die maximale Anzahl von Elementen,  die  der  Aufrufende  in  der  Tabelle  zu
       speichern erwartet.

       Die Funktionen hdestroy() und hdestroy_r() geben die Puffer nicht frei, auf die die Elemente key und data
       der  Einträge  in  der  Hash-Tabelle  weisen.  (Das können sie nicht tun, weil sie nicht wissen, ob diese
       Puffer dynamisch zugewiesen wurden.) Falls diese Puffer freigegeben werden müssen (vielleicht,  weil  das
       Programm  wiederholt  Hash-Tabellen  erzeugt  und wieder freigibt, anstatt eine einzelne Tabelle über die
       Programmlaufzeit hinweg zu pflegen),  dann  muss  das  Programm  Datenstrukturen  zur  Speicherverwaltung
       pflegen, um die Elemente der Tabelleneinträge freigeben zu können.

FEHLER

       SVr4  und  POSIX.1-2001  geben  an,  dass action nur für erfolglose Suchen von Bedeutung ist, so dass ein
       ENTER nichts für eine erfolgreiche Suche tun sollte. In Libc und Glibc (vor  Version  2.3)  verstößt  die
       Implementierung gegen die Spezifikation und aktualisiert in diesem Fall data für den gegebenen key.

       Einzelne Einträge können der Hash-Tabelle hinzugefügt, jedoch nicht gelöscht werden.

BEISPIELE

       Das folgende Programm fügt 24 Einträge in eine Hashtabelle ein und zeigt dann einige davon an.

       #include <stdio.h>
       #include <stdlib.h>
       #include <search.h>

       static char *data[] = { "alpha", "bravo", "charlie", "delta",
            "echo", "foxtrot", "golf", "hotel", "india", "juliet",
            "kilo", "lima", "mike", "november", "oscar", "papa",
            "quebec", "romeo", "sierra", "tango", "uniform",
            "victor", "whisky", "x-ray", "yankee", "zulu"
       };

       int
       main(void)
       {
           ENTRY e;
           ENTRY *ep;

           hcreate(30);

           for (int i = 0; i < 24; i++) {
               e.key = data[i];
               /* Datum ist nur eine Ganzzahl, anstatt eines
                  Zeigers auf irgendwas */
               e.data = (void *) i;
               ep = hsearch(e, ENTER);
               /* Es sollten keine Fehler eintreten */
               if (ep == NULL) {
                   fprintf(stderr, "Eintrag fehlgeschlagen\n");
                   exit(EXIT_FAILURE);
               }
           }

           for (int i = 22; i < 26; i++) {
               /* Zwei Einträge aus der Tabelle ausgeben und zeigen,
                  dass zwei nicht in der Tabelle sind */
               e.key = data[i];
               ep = hsearch(e, FIND);
               printf("%9.9s -> %9.9s:%d\n", e.key,
                      ep ? ep->key : "NULL", ep ? (int)(ep->data) : 0);
           }
           hdestroy();
           exit(EXIT_SUCCESS);
       }

SIEHE AUCH

       bsearch(3), lsearch(3), malloc(3), tsearch(3)

KOLOPHON

       Diese  Seite  ist  Teil  der  Veröffentlichung  5.10  des Projekts Linux-man-pages. Eine Beschreibung des
       Projekts, Informationen, wie Fehler gemeldet werden können sowie die aktuelle Version dieser Seite finden
       sich unter https://www.kernel.org/doc/man-pages/.

ÜBERSETZUNG

       Die deutsche Übersetzung dieser Handbuchseite wurde von Martin Eberhard Schauer <Martin.E.Schauer@gmx.de>
       und Mario Blättermann <mario.blaettermann@gmail.com> erstellt.

       Diese Übersetzung ist Freie Dokumentation; lesen Sie die GNU General Public License Version 3 oder  neuer
       bezüglich der Copyright-Bedingungen. Es wird KEINE HAFTUNG übernommen.

       Wenn  Sie  Fehler  in  der Übersetzung dieser Handbuchseite finden, schicken Sie bitte eine E-Mail an die
       Mailingliste der Übersetzer.

GNU                                             1. November 2020                                      HSEARCH(3)