DEE*_*DAV 1 c++ string dictionary stl
stringto 的映射int工作正常。
std::map<std::string, int> // working
Run Code Online (Sandbox Code Playgroud)
但我想将C-style字符串映射到int
例如:
char A[10] = "apple";
map<char*,int> mapp;
mapp[A] = 10;
Run Code Online (Sandbox Code Playgroud)
但是当我尝试访问映射到“apple”的值时,我得到的是一个垃圾值而不是 10。为什么它的行为与std::string?
Run Code Online (Sandbox Code Playgroud)map<char*,int> mapp;
他们这里的键类型不是"c string"。至少不是,如果我们将 c 字符串定义为“一个字符数组,带有空终止符”。键类型char*是一个指向字符对象的指针。区别很重要。您没有在地图中存储字符串。您正在存储指针,而字符串位于其他地方。
除非您使用自定义比较函数对象,否则默认std::map使用operator<(const key_type&,key_type&)。两个指针相等当且仅当它们指向同一个对象。
以下是三个对象的示例:
char A[] = "apple";
char B[] = "apple";
const char (&C)[6] = "apple"
Run Code Online (Sandbox Code Playgroud)
前两个是数组,第三个是左值引用,它绑定到一个也是数组的字符串文字对象。作为独立的对象,它们的地址当然也不同。所以,如果你要写:
mapp[A] = 10;
std::cout << mapp[B];
std::cout << mapp[C];
Run Code Online (Sandbox Code Playgroud)
每个输出将为 0,因为您尚未初始化mapp[B]或mapp[C],因此它们将由 进行值初始化operator[]。即使每个数组包含相同的字符,键值也不同。
解决方案:不要operator<用于比较指向 c 字符串的指针。使用std::strcmp来代替。使用std::map,这意味着使用自定义比较对象。但是,您还没有完成警告。您仍然必须确保字符串必须保留在内存中,只要它们被映射中的键所指向。例如,这将是一个错误:
char A[] = "apple";
mapp[A] = 10;
return mapp; // oops, we returned mapp outside of the scope
// but it contains a pointer to the string that
// is no longer valid outside of this scope
Run Code Online (Sandbox Code Playgroud)
解决方案:注意作用域,或者只使用std::string.