繁体   English   中英

C ++ - 如何存储多维向量?

[英]C++ - How are multi-dimensional vectors stored?

我有两个关于向量的问题。

  1. 让我们说我有一个多维向量如下: -

    vector< vector<int> > A;

    然后A[0]A[1]等是向量。 矢量如何存储在A 我的意思是关于向量A[0]A[1]哪些信息存储在A 并且A[2]等各个向量的记忆重新分配是否会导致A重新分配?

  2. 其次,我试着看看矢量的地址如何随着重新分配而改变。 我使用了以下代码: -

码:

vector<int> A;
int* x ;
int* y ;

vector<int>* ad;
vector<int>* bd;

for(int i = 0 ; i < 10000; i++){

    A.push_back(i);
    if(i == 2){
        y = &A[0];
        ad = &A;
    }
    x = &A[0];
    bd = &A;    

}

我发现,即使A[0]的地址发生变化, A的地址也不会改变。 这是预期的,因为矢量通过使用newdelete在后台工作。 但我的问题是有多少关于矢量的信息(或哪些信息)存储在地址&A (考虑到&A的地址没有改变)。 这是我对第一个问题的问题。

我试图更好地了解矢量默认情况下的工作方式。

关于向量的多少信息(或哪些信息)存储在地址&A

假设向量的数据与向量对象本身分开存储(通常在动态内存中),这是正确的。

矢量对象本身需要知道的三件事是

  • 矢量数据的位置 - 我们需要它来执行[]运算符,
  • 当前分配的大小 - 我们需要知道何时增长数组,以及
  • 实际放入向量中的元素数量 - 我们需要知道push_back以及从size()返回的内容。

不同的实现是可能的,在向量对象本身中存储少至单个指针。 然而,典型的实现存储指向所分配块的开始的指针,指向所分配块的活动部分的末尾的指针,以及指向所分配块的末尾的指针。

关于向量的地址A的地址不会改变,不是因为A是向量,而是因为没有变量的地址在您定义它的函数(或者更确切地说,函数的特定调用)正在执行时发生变化。 我想你可能会混淆A的地址(你的例子中的ad,bd)和A用来存储向量元素的地址(x和y,本质上,在你的例子中)。 向量分配,取消分配或重新分配存储。

请注意, A[0]不是您定义的变量。 它是A.operator[]的调用结果; 所以它的位置可以改变。

关于实际存储在&A :这有点复杂。 您需要查看C ++安装中的头文件vector 或者也许最好在cppreference.com 上查看std :: vector网页 请注意,有很多模板,一些子类,以及一些明确的模板特化,所以就像我说 - 复杂。 您可能需要重新考虑是否真的想深入了解这个容器如何作为一般规则,或者类的公共方法和sizeof()数字现在是否足够。

我是c ++和STL的初学者,所以我只用一些简单的代码测试你的问题; 首先,我有这些代码:

std::vector<int> tmp;
std::cout << sizeof(tmp) << " " << tmp.size() << " " << tmp.capacity << std::endl;

输出是:

12 0 0

然后,我们在向量中插入一些值

for(int i = 0; i != 10; ++i) tmp.push_back(i);
std::cout << sizeof(tmp) << " " << tmp.size() << " " << tmp.capacity << std::endl;

输出是

12 10 16

然后,我们可以得出一个结论,即向量只保留一个指针,因此sizeof()结果没有改变。 所以,你的问题的答案是,子向量的push_back不会导致父向量的重新分配(我不知道如何表达这两个向量的作用)。 有一些简单的代码:

std::vector<int> v1(10);
std::vector<int> v2(10);

int i;
for(i = 0; i != 10; ++i)
    v1[i] = i;
for(i = 0; i != 10; ++i)
    v2[i] = i;

vv.push_back(v1);
vv.push_back(v2);

std::cout << "v1 capacity: " << v1.capacity() << "  v1 size: " << v1.size() << std::endl;
std::cout << "v2 capacity: " << v2.capacity() << "  v2 size: " << v2.size() << std::endl;
std::cout << "vv capacity: " << vv.capacity() << "  vv size: " << vv.size() << std::endl;

for(i = 10; i != 20; ++i)
    v1.push_back(i);
for(i = 10; i != 20; ++i)
    v2.push_back(i);

std::cout << "v1 capacity: " << v1.capacity() << "  v1 size: " << v1.size() << std::endl;
std::cout << "v2 capacity: " << v2.capacity() << "  v2 size: " << v2.size() << std::endl;
std::cout << "vv capacity: " << vv.capacity() << "  vv size: " << vv.size() << std::endl;

输出:

v1 capacity: 10  v1 size: 10
v2 capacity: 10  v2 size: 10
vv capacity: 2  vv size: 2
v1 capacity: 20  v1 size: 20
v2 capacity: 20  v2 size: 20
vv capacity: 2  vv size: 2

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM