在填充std::矢量时使用不同的地址
Different addresses while filling a std::vector
难道不希望两个循环打印的地址相同吗?我是,我不明白为什么(有时)它们不同。
#include <iostream>
#include <vector>
using namespace std;
struct S {
void print_address() {
cout << this << endl;
}
};
int main(int argc,char *argv[]) {
vector<S> v;
for (size_t i = 0; i < 10; i++) {
v.push_back( S() );
v.back().print_address();
}
cout << endl;
for (size_t i = 0; i < v.size(); i++) {
v[i].print_address();
}
return 0;
}
我用许多本地和在线编译器测试了这段代码,得到的输出如下(最后三个数字总是一样的):
0xaec010
0xaec031
0xaec012
0xaec013
0xaec034
0xaec035
0xaec036
0xaec037
0xaec018
0xaec019
0xaec010
0xaec011
0xaec012
0xaec013
0xaec014
0xaec015
0xaec016
0xaec017
0xaec018
0xaec019
我发现这一点是因为在第一个循环中进行一些初始化时,我在程序的后续部分获得了未初始化的对象。我是不是错过了什么?
因为当向量capicity改变时,它会重新分配元素。若您std::vector::保留足够的容量,不需要重新分配,它将打印相同的地址。
vector<S> v;
v.reserve(10);
注意:正确使用std::vector::reserve将提高应用程序性能,因为没有不必要的重新分配和对象复制。
矢量正在执行重新分配,以便根据需要增长。每次这样做时,它都会为数据分配一个更大的缓冲区,并跨其复制元素。您可以在第一个循环中清楚地看到这一点,其中每个地址跳跃后面都有一个更大的连续地址序列。在第二个循环中,您只需查看最终重新分配后的地址。
0xaec010
0xaec031 <--
0xaec012 <--
0xaec013
0xaec034 <--
0xaec035
0xaec036
0xaec037
0xaec018 <--
0xaec019
实例化具有10个S
对象的矢量的最简单方法是
std::vector<S> v(10);
这将不涉及重新分配。另请参见std::vector::reserve
。
矢量元素被连续存储;也就是说,它们在记忆中都排成一行。矢量对象必须为这个连续的元素块分配空间。
你的向量不能无限期地添加东西。它必须扩大分配的空间。内存模型通常不允许我们扩展内存块—我们必须创建一个新的。当向量执行此操作时,它必须将其所有元素移动到新空间。这在你的第一个循环中发生了好几次。
如果你做了:
vector<S> v;
v.reserve(10);
(你可以这样做,因为你知道你最终会得到10个元素),那么就不需要重新分配,地址也不会改变。
我对它们的变化并不感到惊讶。由于向量最初没有大小,因此可能会在初始循环期间重新分配向量一到两次。这将改变向量的基地址。调整大小后,你最终会使用以前使用过的地址,这并非不可能(尽管我觉得这有点令人惊讶。你确定地址的第一部分吗?)
如果你想确保它们不会改变,你需要在开始推送内容之前添加一个v.reserve()
。
- 将数组的地址分配给变量并删除
- 空基优化子对象的地址
- 在c++中用vector填充一个简单的动态数组
- C++ 指针的内存地址和指向数组的内存地址如何相同?
- 如何使用用户输入在C++中正确填充2D数组
- 如何找到大小'x'数组是否完全填充,在C++?
- 在C++中打印指向不同基元数据类型的指针的内存地址
- 如何在c++程序中找到函数的地址
- 向量元素的引用地址与它所指向的向量元素的地址不同.为什么
- 被解释为低级别const的const对象的地址
- Cuda C++:设备上的Malloc类,并用来自主机的数据填充它
- 通过for循环使用用户输入填充列表
- 将地址分配给本地指针后,公共对象的变量将消失
- 为什么我在leetcode上收到AddressSanitizer:地址0x602000000058上的堆缓冲区溢出错误
- 操作员的地址可以启动指针,但填充值是垃圾
- C++填充指向指针**列表的指针,该列表指向指针地址
- 用地址而不是数字填充队列
- 列表类,其中填充了返回时丢失地址的指针
- 在填充std::矢量时使用不同的地址
- 套接字,Unix域UDP c++ recvfrom无法填充源地址