2009-08-05 1 views
1

저는 흥미로운 상황에 직면하고 있으며 모든 것을 공유하고 싶습니다. 확실히, 어떤 사람이 도와 주면 감사 할 것입니다!std :: map :: find (char *)가 디버그 모드에서 64 비트 머신에서 작동하지 않습니다.

#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; 
} 

나는 Windows 2003 Server 64bit를 사용 중입니다. 출력이 "발견되었습니다!" 디버그 모드에서이 프로그램을 컴파일/실행할 때 릴리스 모드에서이 프로그램을 컴파일/실행할 때 출력이 "찾을 수 없음"입니다.

아이디어가 있으십니까?

감사합니다,

Azher는

답변

0

난 그냥 내 Server2008의 64 비트 박스와 모두 디버그에이 시도 및 인쇄 해제 발견 "을!".

아마도 2003 년 문제 일 것입니다. 나는 2003 년 64 비트가 없으므로 그것을 시도 할 수 없다.

6

지도에서 std :: string을 키로 사용해보십시오. char *를 키로 사용하는 경우 map은 char *의 주소를 예상 한대로 비교하지 않습니다. char *를 키로 사용하려면 비교 술어와 템플릿의 세 번째 인수로 map을 인스턴스화해야합니다. '

당신은 혼자 link

+0

감사합니다. 그런 다음 릴리스 모드에서도 작동하지 않아야합니다. 릴리스 모드에서는 작동하지만 디버그 모드에서는 작동하지 않으므로 혼란 스럽습니다. –

+0

디버그 및 릴리스 모드에서 생각이 다르게 작동 할 수 있습니다. 이것은 잘 알려진 문제입니다 (예 : http://www.flounder.com/debug_release.htm) – dimba

+0

idimba, Great !!! 도움 주셔서 감사합니다. –

1

컴파일러 돈을 아니에요 동일하거나 별도의 저장이 같은 문자열을 사용 사용됩니다 -

디버그의 차이 및 구성 릴리스는 여기에 아마 문자열 리터럴이 저장되는 방법 const를 설명 동일한 메모리 내에서 동일한 char 제약을 할당해야한다. 두 개의 cpp 파일에 char 제약 조건이 있으면 주소가 달라집니다.

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

이 비교기는 정적 인 제약에서 포인터를 저장할 수있는 두 pointers.You을 비교 한 후 훨씬 느립니다 :

하나의 아이디어는 비교 :: 수 std지도를 바꿀지도 또는 특수로 선언하는 것입니다.

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

사용 : 당신은 또한 CONST의 char *의 배열을 확인하고 해당 배열에있는 동일한 CString을 포인터하는 CString을의 포인터를 변경할 수

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

. 세트를 사용하는 것은 좋은 생각이다 :

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]; 
} 

사용 : 응답

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 
관련 문제