C++ std::map::find(char*)在调试模式下无法在64位计算机上工作

C++ std::map::find(char*)在调试模式下无法在64位计算机上工作,c++,windows,C++,Windows,我面临着一个有趣的情况,希望与大家分享。当然,如果有人能帮助我,我将不胜感激 #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 cha

我面临着一个有趣的情况,希望与大家分享。当然,如果有人能帮助我,我将不胜感激

#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;
}
#包括“stdafx.h”
#包括
#定义定义名称1“名称1”
#定义定义名称2“名称2”
#定义定义名称3“名称3”
#定义定义名称4“名称4”
结构TInfo
{
常量字符*t名称;
常量字符*TArray1[100];
常量字符*TArray2[100];
};
typedef std::map TInfoMap;
typedef std::pair TInfoPair;
静态TInfoMap TInfoMap;
TInfo TInfoArray[]=
{
{DEF_NAME1,{'},{'},
{DEF_NAME2,{'},{'},
{DEF_NAME3,{'},{'},
{DEF_NAME4,{'},{'}
};
TInfoMap*getInfoMap()
{
对于(int i=0;i<3;i++)
insert(TInfoPair(TInfoArray[i].TName,&TInfoArray[i]);
return&tinfomap;
}
int _tmain(int argc,_TCHAR*argv[]
{
char*name=“NAME3”;
TInfo*ptr=新的TInfo();
TInfoMap*map1=GetTInfoMap();
如果(map1->find(name)==map1->end())
printf(“未找到”);
其他的
printf(“找到了!”);
返回0;
}
我使用的是64位windows 2003服务器。当我在发布模式下编译/运行这个程序时,我得到了输出“Found!”,而当我在调试模式下编译/运行这个程序时,输出是“notfound”

有什么想法吗

问候,


Azher

我刚刚在我的server2008 64位盒子上尝试了这个,调试和发布打印“找到了!”


所以可能是2003年的某一期。我没有2003 64位,所以无法尝试。

我只是在我的server2008 64位框上尝试了这个,调试和发布打印都“找到了!”


所以可能是2003年的某一期。我没有2003 64位,所以不能尝试使用它。

尝试使用std::string作为映射中的键。 当您使用char*作为键时,map会比较char*的地址,而不是您所期望的内容。如果您想使用char*作为键,您需要使用compare谓词实例化映射,并将第三个参数与模板进行比较

这里调试和发布配置之间的差异可能解释了常量字符串文字是如何存储的——相同的字符串使用相同的存储还是单独的存储


您并不孤单

尝试使用std::string作为map中的键。 当您使用char*作为键时,map会比较char*的地址,而不是您所期望的内容。如果您想使用char*作为键,您需要使用compare谓词实例化映射,并将第三个参数与模板进行比较

这里调试和发布配置之间的差异可能解释了常量字符串文字是如何存储的——相同的字符串使用相同的存储还是单独的存储


编译器不必在同一内存中分配相同的char约束,这并不是唯一的。如果在两个cpp文件中有char约束,则地址将不同

一种方法是将map更改为std::map或使用特殊的Compare进行声明:

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

您还可以创建一个const char*数组,并将cstring的指针更改为指向在该数组中找到的相同cstring的指针。使用set是个好主意:

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

编译器不必在同一内存中分配相同的char约束。如果在两个cpp文件中有char约束,则地址将不同

一种方法是将map更改为std::map或使用特殊的Compare进行声明:

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

您还可以创建一个const char*数组,并将cstring的指针更改为指向在该数组中找到的相同cstring的指针。使用set是个好主意:

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