Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/163.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ c++;矢量对象地址和数据地址混淆_C++_Pointers_Memory_Memory Management_Reference - Fatal编程技术网

C++ c++;矢量对象地址和数据地址混淆

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

我创建了一个向量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;

}

向量的工作方式由实现定义。但是,默认情况下,它们需要将其元素动态存储在空闲存储区中。这意味着当您创建一个
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-style
int[]
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