与 std::vector 的指针进行比较以检查相等性是否安全
Is it safe to compare to pointer of std::vector to check equality?
,我创建了一个指向std::vector
的指针点,然后我对该向量进行了一些push_back
,reserve
,resize
操作,在此类操作之后,将指针与该向量的地址进行比较以检查指针是否指向该向量是否安全,因为可能会有一些内存的重新分配。
例如
std::vector<int> vec;
vector<int>* pVec = &vec;
vec.reserve(10000);
assert(pVec == &vec);
vec = anotherVec;
assert(pVec == &vec);
更重要的是,将指针与 Vector 的第一个值进行比较是否安全?例如:
std::vector<int> vec(1,0);
int* p = &vec[0];
// some operation here
assert(p == &vec[0]);
正如我自己测试的那样,似乎第一种情况是安全的,而第二种情况则不是,但我不能确定。
std::vector<int> vec;
vector<int>* pVec = &vec;
vec.reserve(10000);
assert(pVec == &vec);
是安全的。
std::vector<int> vec(1,0);
int* p = &vec[0];
// some operation here
assert(p == &vec[0]);
不安全。
第一个块是安全的,因为即使其内容发生变化,地址vec
也不会更改。
第二个块是不安全的,因为vec[0]
的地址可能会改变;例如,当vec
调整自身大小时——例如,当你向它push_back元素时。
似乎第一种情况是安全的,而第二种情况则不是
没错。 在第一种"情况"中,无论reserve
调用如何,vec
对象本身都保留在内存中的任何位置,这可能会将托管元素移动到动态内存的另一个区域。 这是因为可以移动元素,因此在第二种情况下指针可能不会相等。
第二种情况是安全的,只要不搬迁。如果您事先知道所需的大小并在获取指针之前使用reserve()
则它是完全安全的,并且可以节省一点性能(减少一个间接级别)。
但是,例如,任何带有push_back()
的添加都可能超出分配的空间并使指针无效。 std::vector
经过优化,如果可能的话,会尝试在同一位置分配更多内存(因为它可以节省复制数据),但您无法确定这一点。
就此而言,您可以采用迭代器,而不是使用指针,因为向量上的迭代器的行为与指针完全相同(并且对性能没有影响),具有更多的类型安全性。
vector<int>* pVec = &vec;
对std::vector<int>
对象的地址进行操作,该地址在作用域之前有效。 vec = anotherVec;
不会更改 vec 的地址,因为这里调用了 std::vector
的operator =
。因此,两个assert(pVec == &vec);
都已成功通过。
在int* p = &vec[0];
的情况下,这取决于:请参阅Iterator invalidation
。
第一种情况确实是安全的,因为没有向量对象地址改变的危险。只要不发生重新分配,第二种情况是安全的(可以使用 std::vector::capacity 成员函数跟踪重新分配),否则它要么是未定义的,要么是实现定义的,具体取决于语言的版本。有关更多信息,请参阅此答案。因为在这种情况下适用相同的限制。
- 检查是否以特定精度给出双精度
- 地图计数确实很重要,或者只是检查是否存在
- 检查是否安装了 windows10 C++
- 模板化检查是否存在带有参数列表的类成员函数?
- 如何巧妙地编写两个函数——一个用于检查是否存在解决方案,另一个用于获取所有解决方案
- MPI:检查是否有任何进程已终止
- 给定一个大小为 N 的数组 S,检查是否可以将序列拆分为两个序列
- Vulkan 的传输队列系列功能和显卡支持:条件检查是否准确?
- 如何检查是否定义了固定宽度的整数
- 使用预处理指令检查是否包含标头?
- 在预处理器中检查 g++ 是否使用 -fopenmp 调用
- 将字符串转换为整数类型T,检查是否存在溢出
- C++编译时检查是否可以用某种类型的参数调用重载函数
- 检查是否至少设置了一点而不跳跃
- 在if条件下,右或左改变值的相等性检查是否有任何区别
- C++ 检查是否按下了键,而不是按住了
- 如何在 c++ 中解析包含整数的字符串并检查是否大于最大值
- 检查是否为质数大o
- 检查是否需要 utf8 转换并转换为 utf8
- 如何正确检查 c++ 是否存在注册表项?