Check alle échte Black Friday-deals Ook zo moe van nepaanbiedingen? Wij laten alleen échte deals zien

[C++] map (associative array) raakt waarden kwijt?

Pagina: 1
Acties:

  • Boondock_Saint
  • Registratie: Januari 2001
  • Laatst online: 18-11-2023
Ik heb de volgende functie geschreven:

C++:
1
2
3
4
5
6
7
8
9
10
11
12
map<const char*, int> *SearchText::countWords()
{
    map<const char*, int> *table = new map<const char*, int>;
    
    (*table)["aap"] = 1;
    (*table)["noot"] = 2;
    
    cout << (*table)["aap"] << endl;
    cout << (*table)["noot"] << endl;
    
    return table;
}


Die ik als volgt gebruik:

C++:
1
2
3
4
5
6
7
8
9
try {
    SearchText *text = new SearchText("test.txt");
    map<const char*, int> *table = text->countWords();
    cout << (*table)["aap"] << endl;
    cout << (*table)["noot"] << endl;
}
catch(int ex) {
    cout << "Could not open file." << endl;
}


Het probleem is nu de volgende output krijg:
1
2
0
0
Oftewel: In de eerste twee output statements (in de functie zelf) geeft table netjes z'n waarde af, terwijl table dat bij de laatste twee dat niet doet.

Het lijkt op een geheugenallocatie probleem, maar ik snap niet precies hoe ik het nog anders kan doen. Ja, ik zou malloc kunnen proberen, maar het moet met new toch ook kunnen?

[ Voor 0% gewijzigd door Boondock_Saint op 11-09-2007 17:51 . Reden: Code iets leesbaarder gemaakt ]

Blasphemy is a victimless crime


  • .oisyn
  • Registratie: September 2000
  • Nu online

.oisyn

Moderator Devschuur®

Demotivational Speaker

[.edit: la maar, hier stond onzin]

Het is logisch. Je gebruikt pointers als keys. De ene keer dat je "aap" gebruikt hoeft niet per se dezelfde pointer op te leveren als de andere keer dat je "aap" gebruikt. Toevallig verpakt jouw compiler de twee referenties naar "aap" in SearchText::countWords() in een enkele string waardoor het in die functie goed gaat. Daarbuiten gaat het echter fout.

Gebruik std::map<std::string, int> > of std::map<const char*,int,string_less>, waarbij string_less een door jouw geimplementeerde functor is die de daadwerkelijke strings comparet ipv alleen de pointers.

[ Voor 77% gewijzigd door .oisyn op 11-09-2007 17:59 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • Boondock_Saint
  • Registratie: Januari 2001
  • Laatst online: 18-11-2023
.oisyn schreef op dinsdag 11 september 2007 @ 17:50:
Welke compiler gebruik je? Ik gok dat jouw implementatie geen specialisatie heeft voor std::less<const char*>, waardoor er gewoon keihard pointers vergeleken worden ipv de daadwerkelijke inhoud van de strings. Dat gaat goed in dezelfde functie omdat de compiler daar identieke strings naar hetzelfde geheugenadres collapset. Output gewoon eens de contents van de map ipv specifieke waarden op te zoeken. En probeer het ook eens met std::string ipv een const char*
Ik gebruik MinGW onder Windows XP (stom, had ik gelijk moeten zeggen :) )

Als ik er doorheen loop dan zitten alle waarden erin (sterker nog, die 0 en 0 ook alletwee, dus 0, 0,1,2).

Dus wat ik dan moet doen is zelf een compare functie maken en dan gelijk overstappen op string objecten?

/edit

aha ok, dus als ik overstap op std::string, dan hoef ik geen compare functie te schrijven?

[ Voor 5% gewijzigd door Boondock_Saint op 11-09-2007 18:00 ]

Blasphemy is a victimless crime


  • Boondock_Saint
  • Registratie: Januari 2001
  • Laatst online: 18-11-2023
Thanx!


map<string, int> works like a charm :)

Blasphemy is a victimless crime


  • .oisyn
  • Registratie: September 2000
  • Nu online

.oisyn

Moderator Devschuur®

Demotivational Speaker

Kost natuurlijk wel iets meer geheugen omdat een string de data kopiëert naar z'n eigen buffer. Een eigen compare functie is veelal iets efficienter:
C++:
1
2
3
4
5
6
7
8
9
struct string_less
{
    bool operator() (const char * a, const char * b)
    {
        return strcmp(a,b) < 0;
    }
};

std::map<const char *, int, string_less> mymap;

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 13-09 00:05
Daar staat tegenover dat je met een map<const char*, int> natuurlijk wel de vraag in het midden laat wie de owner is van de char[]s. In dit simpele voorbeeld zijn het char[]s met static lifetime, dus hoef je ze niet op te ruimen, maar dat is natuurlijk in ingewikkeldere voorbeelden zeldzamer.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein

Pagina: 1