2009-08-05 6 views
1

Ich bin mit einer interessanten Situation konfrontiert und möchte mit allen teilen. Definitiv, wenn jemand helfen kann, werde ich dankbar sein!std :: map :: find (char *) funktioniert nicht auf 64bit Maschine im Debug-Modus

#include "stdafx.h" 
#include <map> 

#define DEF_NAME1 "NAME1" 
#define DEF_NAME2 "NAME2" 
#define DEF_NAME3 "NAME3" 
#define DEF_NAME4 "NAME4" 

struct TInfo 
{ 
    const char * TName; 
    const char * TArray1[100]; 
    const char * TArray2[100]; 
}; 

typedef std::map<const char*, TInfo*> TInfoMap; 
typedef std::pair<const char*,TInfo*> TInfoPair; 

static TInfoMap tinfomap; 

TInfo TInfoArray[] = 
{ 
{DEF_NAME1,{""}, {""}}, 
{DEF_NAME2,{""}, {""}}, 
{DEF_NAME3,{""}, {""}}, 
{DEF_NAME4,{""}, {""}} 
}; 

TInfoMap* GetTInfoMap() 
{ 

for (int i = 0; i < 3 ; i++) 
    tinfomap.insert(TInfoPair(TInfoArray[i].TName,&TInfoArray[i])); 

return &tinfomap; 
} 


int _tmain(int argc, _TCHAR* argv[]) 
{ 
char *name="NAME3"; 

TInfo* ptr = new TInfo(); 

TInfoMap* map1 = GetTInfoMap(); 

if (map1->find(name) == map1->end()) 
    printf("Not found"); 
else 
    printf("Found!"); 

return 0; 
} 

Ich bin auf Windows 2003 Server 64bit. Ich bekomme die Ausgabe "Found!" wenn ich dieses Programm im Freigabemodus kompiliere/laufe und die Ausgabe "Nicht gefunden" ist, wenn ich dieses Programm im Debug-Modus kompiliere/laufe.

Irgendeine Idee?

Grüße,

Azher

Antwort

0

Ich habe gerade versucht, diese auf meinem Server2008 64-Bit-Feld und beide Debug-und Release-print "Gefunden!".

Also wahrscheinlich eine 2003 Ausgabe einer Art. Ich habe kein 2003 64bit also kann das nicht versuchen.

6

Versuchen Sie, std :: string als Schlüssel in der Karte zu verwenden. Das Problem, wenn Sie char * als Schlüssel verwenden, vergleicht map die Adresse von char * und nicht deren Inhalt wie erwartet. Wenn Sie char * als Schlüssel verwenden möchten, müssen Sie die Zuordnung mit Vergleichsprädikat und ein drittes Argument für die Vorlage instanziieren.

Der Unterschied zwischen Debug und Konfiguration hier Lassen Sie vielleicht erklärt, wie const Stringliterale gespeichert sind - ist gleich oder getrennte Lagerung für die gleiche Zeichenfolge verwendet verwendet wird

Du bist nicht allein link

+0

Vielen Dank für die Antwort. Dann sollte es auch im Release-Modus nicht funktionieren. Es ist verwirrend, weil es im Freigabemodus funktioniert, aber nicht im Debug-Modus. –

+0

Denken kann in Debug- und Release-Modi anders funktionieren. Dies ist ein bekanntes Problem (zum Beispiel http://www.flounder.com/debug_release.htm) – dimba

+0

idimba, Großartig !!! Danke für die Hilfe –

1

Compiler don‘ t müssen im selben Speicher die gleiche char constraint zuweisen. Wenn Sie in einer cpp-Datei eine char-Einschränkung haben, ist die Adresse anders. Vergleichen

Eine Idee ist Karte zu ändern, um mit spezieller std :: map oder erklären:

class CompareCString 
{ 
    bool operator()(const char* one,const char* two) { return strcmp(one,two)>0; }; 
}; 
typedef std::map<const char*, TInfo*, CompareCString> TInfoMap; 

Dieser Komparator ist viel langsamer als nur zwei pointers.You Vergleich könnte den Zeiger in statischen Einschränkungs speichern.

#define DEFINE_NAME(X) const char * X = #X ; 
DEFINE_NAME(NAME1) 
DEFINE_NAME(NAME2) 
TInfo TInfoArray[] = 
{ 
    {NAME1,{""}, {""}}, 
    {NAME2,{""}, {""}}, 
}; 

Verwendung:

map1->find(NAME1); // it should work. 

Sie auch ein Array von const char * machen könnte und den Zeiger ändern von cstring auf identische cstring in diesem Array gefunden Zeiger. Mit Set ist eine gute Idee:

typedef set<const char *,CompareCString> IternStringSet; 
const char* iternStringSetData[] = 
{ 
    "Name1","Name2","Name3","Name4" 
}; 
enum IternStringNames 
{ 
    Name1,Name2,Name3,Name4 
}; 
IternStringSet iternStringSet(iternStringSetData,iternStringSetData+4); 
const char* intern(const char* name) 
{ 
    IternStringSet::iterator i = iternStringSet.find(name); 
    return (i=!iternStringSet.end()) ? *i : NULL; 
} 
const char* intern(IternStringNames name) 
{ 
    return iternStringSetData[name]; 
} 

Verwendung:

const char* what = intern("Name1"); slower ,using strcmp, but done once 
map1->find(what); // faster, not using strcmp 

map1->find(intern(Name1)); // faster, not using strcmp 
Verwandte Themen