我创建了一个向量 a 并尝试显示& a 和& a [0] 。地址非常不同。对象地址通常与第一个元素地址相同吗?对象记忆是不是连续的?我注意到& a + 1 和& a 之间的地址差异与整个矢量元素的大小完全相同,在这种情况下为12个字节。它看起来像是我整个矢量的副本。
#include <iostream>
#include <vector>
using namespace std;
int main(){
vector<int> a ={3,5,8};
cout<<"vector object address: "<<&a<<endl;
cout<<"vector object address +1: "<<&a+1<<endl;
cout<<"vector data[0] address: "<<&a[0]<<endl;
cout<<"vector data[1] address: "<<&a[1]<<endl;
return 0;
}
任何人都可以向我解释矢量对象的工作原理吗?下面是代码输出:
vector object address: 0034FEBC
vector object address +1: 0034FEC8
vector data[0] address: 007D8208
vector data[1] address: 007D820C
答案 0 :(得分:0)
矢量的工作原理是实现定义的。但是,默认情况下,它们需要在免费存储上动态存储其元素。这意味着当您创建std::vector
时,它会分别为其成员获取内存。
它可以实现如下:
template<typename T>
class vector
{
public:
// The returned element will not have the same address as this
T& operator[](std::size_t n) { return m_begin[n]; }
private:
T* m_begin; // start of internal array
T* m_top; // end of contained elements
T* m_end; // end of internal array
};
注意:上述模型中缺少重要部分
元素的地址直接存储在矢量对象中,而不是元素本身。
答案 1 :(得分:0)
您所看到的内容的解释是std::vector
不像原始c风格数组那样遵循array decaying的相同规则:
#include <iostream>
using std::cout;
using std::endl;
int main() {
int a[] ={3,5,8};
cout<<"raw array object address: "<<&a<<endl;
cout<<"raw array object address +1: "<<&a+1<<endl; // adds sizeof(a)
cout<<"raw array data[0] address: "<<&a[0]<<endl; // same as a + 0
cout<<"raw array data[1] address: "<<&a[1]<<endl; // same as a + sizeof(int)
}
输出:
raw array object address: 0x7ffd02ca2eb4 raw array object address +1: 0x7ffd02ca2ec0 raw array data[0] address: 0x7ffd02ca2eb4 raw array data[1] address: 0x7ffd02ca2eb8
有人可以向我解释矢量对象的工作原理吗?
std::vector
实例是非POD变量,并且在本地存储中具有自己的地址。它只包装实际用于存储数据的底层内存地址。 实现定义究竟是什么,但您可以认为至少有一个实习指针,并且allocator concept用于获取内存。
跟踪当前大小,并复制到重新分配的内存也是如此。
std::vector::data()
函数专用于访问有保证的连续内存块。
您应该注意到,通过上述data()
函数获得的指针不稳定,并且在某种程度上操作std::vector
后可能会失效。
另外值得一提的是std::array
在其他标准容器中例外:
#include <iostream>
#include <array>
using std::array;
using std::cout;
using std::endl;
int main() {
array<int,3> a ={3,5,8};
cout<<"std::array object address: "<<&a<<endl; // Note these addresses ...
cout<<"std::array object address +1: "<<&a+1<<endl;
cout<<"std::array data[0] address: "<<&a[0]<<endl; // are the same
cout<<"std::array data[1] address: "<<&a[1]<<endl;
}
输出:
std::array object address: 0x7ffe72f1cf24 std::array object address +1: 0x7ffe72f1cf30 std::array data[0] address: 0x7ffe72f1cf24 std::array data[1] address: 0x7ffe72f1cf28
答案 2 :(得分:0)
除了@Galik所说的,我还会提到&a
和&a+1
之间的关系并不是你所期望的。考虑:
#include<iostream>
#include<vector>
int main() {
std::vector<int> a = {3,5,8,234,324,324};
std::vector<int> b = {1};
std::cout<<sizeof(a)<<std::endl;
std::cout<<&a<<std::endl;
std::cout<<&a+1<<std::endl;
std::cout<<sizeof(b)<<std::endl;
std::cout<<&b<<std::endl;
std::cout<<&b+1<<std::endl;
return 0;
}
我的输出是:
24
0x7fffc48c6ca0
0x7fffc48c6cb8
24
0x7fffc48c6cc0
0x7fffc48c6cd8
两个数组都有sizeof
24,并且向指针添加1会使地址增加相同的数量(18十六进制为24)。无论元素数量多少!你正在做的是查看向量的数据结构的大小,它包含一个指向数组的指针,因此没有得到“真正的”大小(它是真实的,只是该类包含一个指针,而不是数据,因此不受其影响。)
这与数据本身无关,保证连续,如您的示例所示([0]
和[1]
的两个地址完全由sizeof(int)==4
分隔你的情况)。
答案 3 :(得分:0)
向量由两部分组成。一个是对象本身,它是固定大小。另一个是向量中包含的数据,它是可变的。向量对象的一个成员将是向量包含的数据的指针。 &a
返回一个指向矢量对象的指针,&a[0]
返回一个指针,该指针指向与该对象位于同一位置的不的数据。
&a
为您提供指向矢量对象的指针。当您执行&a+1
时,您将使用指针算法,这将为您提供指向向量数组中下一个向量的指针。由于你没有数组,&a+1
正在返回一个无效指针,但是C ++没有任何方法可以知道它。