从不改变对象状态的函数中使用std :: map时注意到一种奇特的行为:
std::map<std::string, int> _attribLocations;
...
int ProgramInfo::getAttribLocation(const std::string& name) const
{
return _attribLocations.at(name);
}
当我调用此函数时,传递一个字符串文字,查找会抛出out_of_range异常:
auto index = info.getAttribLocation("v_position");
我注意到有两个版本的at(),一个使用const_iterator,另一个不使用:
mapped_type& at(const key_type& _Keyval)
{ // find element matching _Keyval
iterator _Where = _Mybase::lower_bound(_Keyval);
if (_Where == _Mybase::end()
|| _Mybase::_Getcomp()(_Keyval, _Mybase::_Key(_Where._Mynode())))
_Xout_of_range("invalid map<K, T> key");
return (_Where->second);
}
const mapped_type& at(const key_type& _Keyval) const
{ // find element matching _Keyval
const_iterator _Where = _Mybase::lower_bound(_Keyval);
if (_Where == _Mybase::end()
|| _Mybase::_Getcomp()(_Keyval, _Mybase::_Key(_Where._Mynode())))
_Xout_of_range("invalid map<K, T> key");
return (_Where->second);
}
};
似乎导致它抛出的部分是:
_Mybase::_Getcomp()(_Keyval, _Mybase::_Key(_Where._Mynode()
))
我没有比这更深入地调试。
我正在使用Visual Studio 2015.
我确定传递的密钥确实存在于地图中(从使用调试器检查地图)。它可能是地图实现中的错误,或者我错过了比较字符串的内容吗?
答案 0 :(得分:1)
class A
{
public:
A()
{
char* foo = (char*)malloc(40000);
foo[0] = 'f';
foo[1] = 'o';
foo[2] = 'o';
for (int i = 3; i < 40000; i++)
foo[i] = '\0';
std::string fooStr(foo, 40000);
map[fooStr] = 5;
}
int getAttribLocation(const std::string name)
{
return map[name];
}
private:
std::map<std::string, int> map;
};
int main()
{
A instance;
auto x = instance.getAttribLocation("foo");
return 0;
}
混淆来自于在[]和at()之间切换,因为我无法在常量函数中使用[]。