Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » stl hash_map

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 <
000
03.05.2004, 08:22 Uhr
nano



Ich hab da ein großes kleines Problem mit den stl hash_map s.
Erst mal mein code:

C++:
struct eqstr {
    bool operator()(const char* s1, const char* s2) const {
        //cout << "from eqstr: " << s1 << " == " << s2 << " ? " << (strcmp(s1, s2) == 0) << endl;
        return strcmp(s1, s2) == 0;
    }
};

typedef set<gid_t> gidSet_t;
typedef hash_map<const char*, gidSet_t, hash<const char*>, eqstr> valueMap_t;
typedef hash_map<const char*, valueMap_t, hash<const char*>, eqstr> nameMap_t;
typedef hash_map<const char*, char, hash<const char*>, eqstr> chgMap_t;

struct valueIdPair {
    char value[VALUE_LEN+1];
    gid_t gid;
};

char addEntry(char* name, char* value, gid_t gid, char chg) {
        valueMap_t valueMap;
        gidSet_t gidSet;
        
        chgMap[name] = chg;
        nameMap.insert(nameMap_t::value_type(name, valueMap));
        nameMap[name].insert(valueMap_t::value_type(value, gidSet));
        pair<gidSet_t::iterator, bool> result = nameMap[name][value].insert(gid);
        if(result.second)
            return 0;
        else
            return 1;
}



So nun zu meinem Problem:
die funktion addEntry functioniert prächtig wenn ich die Parameter direkt belege:
C++:
addEntry("testname","testvalue",1);


Wenn ich das ganze über den struct valueIdPair versuche funktioniert die hash funktion nicht richtig und einzelne schlüssel werden überschrieben und die daten sind nur chaos.
Ich benötige den struct um die Indexstruktur in einer Binärdatei zu speichern.
Die kann ich dann auch gut auslesen und erhalte:


C++:
valueIdPair valid;
valid.value;
valid.gid;


Ich wandle dann vaild.value in einen char* um:

C++:
valid.value[VALUE_LEN+1] = '/0';
char *val = &valid.value[0];


Habs auch schon so probiert:

C++:
string tmp_value = val_id.value;
char *val = (char*)tmp_value.c_str();


aber beim aufruf von

C++:
addEntry("testname",val,2);

passiert der obengenannte Fehler!

Was mach ich falsch?
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
03.05.2004, 10:30 Uhr
nano



Vieleicht sollte ich das Problem noch etwas näher beschreiben:

Angenommen es soll einen Key in die nameMap eingetragen werden. Der Key adressiert dann die valueMap in welche zwei Keys eingetragen werden soll.
Jeder Key aus der value map adressiert ein set von ids (hier gid_t = int)

Der name Key und die valueMap werden ohne Probleme erzeugt. Der erste Key in der valueMap auch. Jetzt werden die id in das set des ersten value keys eingetragen. Das funktioniert auch noch.
Ich überprüfe das ganze nach jedem addEntry aufruf mit einer report funktion:

C++:
void report() {
    nameMap_t::iterator nameIter;
    valueMap_t::iterator valueIter;
    gidSet_t::iterator idIter;
    for (nameIter = nameMap.begin(); nameIter != nameMap.end(); nameIter++) {
        cout << "#NAME: "<< (*nameIter).first << " changed? " <<  chgMap[(*nameIter).first] << endl;
        for(valueIter = (*nameIter).second.begin(); valueIter != (*nameIter).second.end(); valueIter++ ) {
                cout << "#VALUE: " << (*valueIter).first << endl;
            for(idIter = (*valueIter).second.begin(); idIter !=(*valueIter).second.end(); idIter++) {
                cout << "#GID: " << (*idIter) << endl;    
            }
        }
    }
}


So soll jetzt ein zweiter Schlüssel in die valueMap bekomme ich eine Ausgabe von der report funktion die mir mitteilt das der erste key der valueMap überschrieben wurde. Es werden laut report funktion ausserdem keine ids mehr in das set eingefügt.
Adressiere ich das ganze später wieder direkt mit einem Schlüssel der Form "value1". Ist das set des ersten value key leer und die id für den zweiten Schlüssel sind da, wurden beim eintragen aber nicht von der report funktion gefunden.
Ich denke mir da läuft was mit der hash funktion schief. Aber was und warum?
Und warum funktioniert das ganze wenn ich die Parameter direkt ("..") an die Funktion übergebe. Ich hoffe nur ich hab Scheiße gebaut und nicht sgi.

Ihr fragt euch jetzt warum braucht der so einen Scheiß?
Das soll eine Indexstruktur für eine Graph Datenbank werden.
Angenommen jeder garph, jeder Knoten und jede Kante hat Attribute, also ein name=wert paar. Nun will man eine informelle abfrage starten, welche Garphen ein bestimmtes Attribut, selbst oder in einem ihrer Knoten bzw. Kanten, besitzen. Dafür ist nun dieser Index zusatändig. Der Index wird immer dann aktualisiert wenn ein neuer Graph in die Datenbank aufgenommen wird.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
03.05.2004, 11:37 Uhr
nano



Komando zurück, hab mitlerweile das problem gefunden.

Während hash_map<char*,T> eine standart hash funktion hat, welche auf dem Inhalt des strings aufbaut, basiert die standart vergleichs methode equal_key<char*> auf der Adresse des Strings und nicht auf dessen Inhalt.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
03.05.2004, 11:42 Uhr
KaraHead



schon faszinierend wie man sich selbst helfen kann
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
03.05.2004, 11:45 Uhr
nano



Allerdings, gell... aber vieleicht hilfts ja auch noch jemandem anders!
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ C / C++ (ANSI-Standard) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: