map<string, int> 从 const 函数调用时会抛出 std::out_of_range
map<string, int> throws std::out_of_range when called from const function
从一个不改变其对象状态的函数中注意到使用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")。我传入了字符串文字,比如"gl_position",但查找实际上没有找到任何内容。我在非常数函数中使用了[]运算符,它返回默认的int(0),这正是我所期望的。但是at()未能找到该值,并引发了。以下是发生的事情:
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] = ' ';
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()之间的切换,因为我不能在常量函数中使用[]。
相关文章:
- 使用std::multimap迭代器创建std::list
- C++中std::resize(n)和std::shrink_to_fit之间的区别
- 来自 std::list 的迭代器 .end() 按预期返回"0xcdcdcdcdcdcdcdcd"但 .begin()
- C++17复制构造函数,在std::unordereded_map上进行深度复制
- 如何导出包含具有"std::unique_ptr"值的"std::map"属性的
- 从持续时间构造std::chrono::system_clock::time_point
- 在 std::unordered_map 中插入新的键/值对会导致"out of range"异常
- swig perl typemap(out) std::vector<std::string> 在 perl 中不返回所需的输出
- "friend std::ostream& operator<<(std::ostream& out, LinkedList& list)"是什么意思?
- 尝试同时写入 std:out 和文件
- 错误:非静态引用成员"std::ostream&Student::out",无法使用默认赋值运算符
- c ++如何使我.get() std::future out of a vector.
- 如何在 Linux 中将孩子的进程 std (out / err) 设置为父级
- fstream::open() Unicode 或非 ASCII 字符在 Windows 上不起作用(使用 std::ios::out)
- C++同时写入 std::out 和 std:clog
- Printing out std::map
- 将Std::vector通过ref / out从c#传递到c++
- QTextStream and std out
- 聚合'std::stringstream out'具有不完整的类型,无法定义 [C++]
- 以std:: Fstream::in | std:: Fstream::out | std:: Fstream::app