map.find和指向向量的指针的怪异行为
Weird behavior with map.find and a pointer to a vector
我有一个向量对到向量向量的映射,看起来像这样:
std::map<std::pair<uint16, uint16>, std::vector<std::vector<uint32> > >
映射是在类的构造函数中填充的。这个类提供了一个公共方法,该方法返回指向std::vector<std::vector<uint32> >
(映射值部分)的指针,如下所示:
typedef std::pair<uint16, uint16> key;
typedef std::vector<std::vector<uint32> > value;
value* FindValues(key someKey) {
std::map<key, value>::const_iterator it;
it = someStore.find(someKey);
if (it != someStore.end())
return &(value)it->second;
return NULL;
}
这就是它变得奇怪的时候。在FindValues返回的向量上迭代时,所有子向量的第一个值都是一个大的负数(如-1818161232)。但如果我使用类似的函数
value FindValues(key someKey) {
std::map<key, value>::const_iterator it;
return someStore.find(someKey)->second;
}
则该值是正常的。只有所有子向量的索引0处的值才会发生这种情况。不过,对于第二种方法,如果找不到键(原因很明显),我的应用程序就会出错。我做错了什么?
如果返回语句真的看起来像
return &(value) it->second;
然后有几件事可以说:
如果您的编译器在不发出诊断消息的情况下接受它,那么它就坏了。在C++中,将内置的一元
&
应用于非引用强制转换的结果是非法的。(value) it->second
表达式生成一个临时对象,一个右值。使用&
无法获取此类对象的地址。代码甚至不应该编译。如果你的编译器接受它作为某种奇怪的"扩展",那么这意味着你确实在获取并返回临时对象的地址。然后,临时对象立即被销毁,使指针指向垃圾。难怪你会通过这样的指针看到一些奇怪的值。
需要某种类型的强制转换是因为您使用了
const_iterator
来存储搜索结果。很明显,你做了一个错误的尝试,试图用你的(value)
演员阵容来消除it->second
的惊愕。正确的方法可能看起来如下return const_cast<value *>(&it->second);
但是你为什么一开始就使用
const_iterator
呢?正确的做法是使用常规的iterator
,只进行return &it->second;
没有任何额外的铸件。
您需要决定要编写哪种
FindValue
方法。如果这应该是一个常量方法,那么它应该返回const value *
,并且应该声明为const
const value* FindValues(key someKey) const
当然,在这种情况下,您应该在内部使用
const_iterator
。如果您的
FindValue
应该是一个非常量方法,那么您可以保留当前声明value* FindValues(key someKey)
但内部使用普通CCD_ 15。
你现在拥有的是两者的某种混合,这就是为什么你不得不求助于奇怪的演员阵容。(事实上,你的类中可能需要两个版本。一个可以通过另一个实现。)
您的typedef
非常具有误导性。这是一条错误的线路:
return &(value)it->second;
看似简单的C样式类型转换实际上是对std::vector
的复制构造函数的调用。这行可以重写为
return &std::vector<std::vector<uint32> >(it->second)
当你重写这一行时,奇怪结果的原因变得显而易见:
std::vector<std::vector<uint32> > result (it->second);
return &result;
实际上,您返回的是一个本地对象的地址,一旦函数返回,该对象就会被销毁。
所以,这个变体会更好。
typedef std::pair<uint16, uint16> key;
typedef std::vector<std::vector<uint32> > value;
value* FindValues(key someKey) {
std::map<key, value>::const_iterator it;
it = someStore.find(someKey);
if (it != someStore.end())
return &const_cast<value&>(it->second);
return 0;
}
- 有没有一种"cleaner"的方法可以在指向基的指针向量中找到派生类的第一个实例?
- 如何更改唯一指针向量的可见性
- 如何在基类指针向量的元素上应用重载的多态函数
- C++:添加新结构时,结构指针向量中的所有元素都会更新
- 包含指向其他结构的指针向量的结构
- 如何将子类作为函数的参数传递给期望基类,然后将该对象传递到指向这些抽象类对象的指针向量中?
- 如何将字符串指针数组转换为字符串类型的智能指针向量?
- 初始化可变数据结构中的共享指针向量
- 指向具有 decltype 的函数的指针向量
- push_back指向指针向量的指针
- 使用指针向量(带代码)C++(以及对其使用的便利性的怀疑)时出现问题
- 我可以做些什么来改进指针向量中的此搜索?
- 指向指针排序向量的指针向量的 C++ 向量
- 初始化用户定义类的指针向量
- 函数无法识别我在C++传递节点指针向量?
- 如何声明指向类对象的指针向量?
- 指向结构的指针向量的元素具有相同的地址
- 删除指向抽象类的指针向量
- 当我返回指向结构的指针向量时出现段错误
- 用基于范围的for循环填充指针向量