C++ c++;矢量对象地址和数据地址混淆
我创建了一个向量a,并试图显示&a和&a[0]。地址非常不同。对象地址通常不是和第一个元素地址相同吗?对象内存不是连续的吗?我注意到&a+1和&a之间的地址差异与整个向量元素的大小完全相同,在本例中为12字节。在我看来,它就像是整个向量的副本C++ c++;矢量对象地址和数据地址混淆,c++,pointers,memory,memory-management,reference,C++,Pointers,Memory,Memory Management,Reference,我创建了一个向量a,并试图显示&a和&a[0]。地址非常不同。对象地址通常不是和第一个元素地址相同吗?对象内存不是连续的吗?我注意到&a+1和&a之间的地址差异与整个向量元素的大小完全相同,在本例中为12字节。在我看来,它就像是整个向量的副本 #include <iostream> #include <vector> using namespace std; int main(){ vector<int> a ={3,5,8}; cout
#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;
}
向量的工作方式由实现定义。但是,默认情况下,它们需要将其元素动态存储在空闲存储区中。这意味着当您创建一个
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
};
模板
类向量
{
公众:
//返回的元素将不具有与此相同的地址
运算符[](std::size_T n){return m_begin[n];}
私人:
T*m_begin;//内部数组的开始
T*m_top;//包含元素的结尾
T*m_end;//内部数组的结尾
};
注意:上述模型缺少关键零件
元素的地址直接存储在vector对象中,而不是元素本身。您看到的解释是,
std::vector
不像原始c样式数组那样遵循相同的规则:
#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)
}
有人能给我解释一下向量物体是如何工作的吗
std::vector
实例是一个非变量,它在本地存储器中有自己的地址。它仅仅包装了实际用于存储数据的底层内存地址。具体定义是如何实现的,但可以考虑至少有一个接口指针,而AN是用来获取内存的。
跟踪当前大小,并管理复制到重新分配的内存
这些函数专用于访问保证连续的内存块
您应该注意到,通过前面提到的data()
函数获得的指针是不稳定的,一旦std::vector
以某种方式操作,指针可能会失效
还值得一提的是,
std::array
在这里与其他标准容器不同:
向量由两部分组成。一个是对象本身,它是固定大小的。另一个是向量中包含的数据,它是可变的。向量对象的一个成员将是指向向量包含的数据的指针
&a
返回指向向量对象的指针,&a[0]
返回指向与对象不在同一位置的数据的指针
&a
为您提供指向向量对象的指针。当您执行&a+1
时,您正在使用指针算法,这将为您提供指向向量数组中下一个向量的指针。因为没有数组,<代码>和A+1 < /Cord>返回无效指针,但是C++没有任何方式知道。请以代码的形式发布代码,而不是以链接或图像的形式发布。欢迎使用SO。“对象地址通常与第一个元素地址相同吗?”-不,与标准容器不同(除了std::array
)。要寻址std::vector
的底层连续数组,请使用以下函数。取std::vector
变量本身的地址是不同的。提到std::array
是一个例外。这两个[]
地址在我看来是相邻的。您是否记得要解释的大小(int)
?@fuhuan26在询问之前最好先咨询一下std::vector
不是c-styleint[]
raw数组的POD替代品。尽管它可以使用前面提到的data()
函数和size()
进行完全转换。关键是POD类型是否为IMO。而std::array
正如您所认为的那样是异常的。当然,当然!我只是尝试了一种不同的解释方法(可能是出于误解)。出现这样的混淆似乎有点自然(对行为的最低期望),因此这个问题没有那么糟糕。嗨,马克,谢谢你的解释。因此,一旦向量对象定义了,&a
值,情况就是这样。但是,&a[0]
值可能会更改,如果向量扩展很多,而原始地址不够大。我说得对吗?您提到向量对象的一个成员是指向向量所包含数据的指针。如何调用该指针?该指针的加法始终与&a[0]
相同,对吗@做记号Ransom@fuhuan26--请注意,std::vector::operator[]
实际上是一个函数调用--它不是类似于数组的内置运算符。所以对于vector,[]
可以做任何它需要做的事情。@fuhuan26由vector
维护的指针是私有的,它可能直接指向数据,但您不能确定,这并不重要,因为您无法访问它<代码>&a[0]是获取数据指针的正确方法。是的,它可以随着向量的容量的改变而改变-标准保证它不会改变,否则。@Mark Ransom,明白了。一旦定义了向量对象,它的地址&a
永远不会改变,即使“容量”改变了,对吗?@fuhuan26,除非该向量是另一个向量的一部分!但是是的,局部变量a
的地址永远不会更改。
#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
#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