C++ - 如何存储多维向量?
C++ - How are multi-dimensional vectors stored?
我有两个关于矢量的问题。
假设我有一个多维向量如下:-
vector< vector<int> > A;
则A[0]
、A[1]
等都是向量。 A
中的向量是如何存储的?我
A[0]
和 A[1]
向量的什么信息存储在 A
中?
并重新分配单个向量的内存,例如 A[2]
也会导致 A
的重新分配?
其次,我试图查看向量的地址如何随着重新分配而变化。我使用了以下代码:-
代码:
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
的地址也不会发生变化。这是意料之中的,因为矢量通过使用 new
和 delete
在后台工作。但我的问题是地址 &A
中存储了多少关于向量的信息(或哪些信息)(考虑到 &A
的地址不会改变)。这也是我对第一个问题的疑问。
我正在尝试更好地理解默认情况下向量的工作方式。
关于vector的地址:A
的地址没有变化,不是因为A是vector,而是因为没有[=29] =] 变量的地址在您定义它的函数(或者更确切地说,您的函数的特定调用)正在执行时发生变化。我认为您可能将 A 的地址(在您的示例中为 ad、bd)与 A 用于存储向量元素的地址(在您的示例中基本上是 x 和 y)混淆了。向量分配、取消分配或重新分配存储。
请注意,A[0]
不是您定义的变量。它是 A.operator[]
调用的结果;所以它的位置可以改变。
关于 &A
中实际存储的内容:这有点复杂。您需要查看 C++ 安装中的头文件 vector
。或者看看 webpage for std::vector at cppreference.com 可能会更好。请注意,有很多模板,一些 subclassing,以及一些明确的模板特化,所以就像我说的 - 复杂。您可能需要重新考虑您是否 真的 想深入了解这个容器作为一般规则是如何工作的,或者 class' public 方法和 sizeof()
这个数字现在已经足够了。
how much information (or which information) about the vector is stored in the address &A
您假设向量的数据与向量对象本身分开存储是正确的 - 通常在动态内存中。
矢量对象本身需要知道的三件事是
- 矢量数据的位置 - 我们需要它来执行
[]
运算符,
- 当前分配的大小 - 我们需要它来知道何时增长数组,并且
- 实际放入向量中的元素数量 - 我们需要它来知道
push_back
的位置以及从 [=13] 到 return 的内容=].
不同的实现是可能的,在矢量对象本身中存储尽可能少的单个指针。然而,一个典型的实现存储了一个指向分配块开始的指针,一个指向分配块活动部分末尾的指针,以及一个指向分配块末尾的指针。
我是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
那么,我们可以得出结论,vector只是保留了一个指针,所以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
我有两个关于矢量的问题。
假设我有一个多维向量如下:-
vector< vector<int> > A;
则
A[0]
、A[1]
等都是向量。A
中的向量是如何存储的?我A[0]
和A[1]
向量的什么信息存储在A
中? 并重新分配单个向量的内存,例如A[2]
也会导致A
的重新分配?其次,我试图查看向量的地址如何随着重新分配而变化。我使用了以下代码:-
代码:
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
的地址也不会发生变化。这是意料之中的,因为矢量通过使用 new
和 delete
在后台工作。但我的问题是地址 &A
中存储了多少关于向量的信息(或哪些信息)(考虑到 &A
的地址不会改变)。这也是我对第一个问题的疑问。
我正在尝试更好地理解默认情况下向量的工作方式。
关于vector的地址:A
的地址没有变化,不是因为A是vector,而是因为没有[=29] =] 变量的地址在您定义它的函数(或者更确切地说,您的函数的特定调用)正在执行时发生变化。我认为您可能将 A 的地址(在您的示例中为 ad、bd)与 A 用于存储向量元素的地址(在您的示例中基本上是 x 和 y)混淆了。向量分配、取消分配或重新分配存储。
请注意,A[0]
不是您定义的变量。它是 A.operator[]
调用的结果;所以它的位置可以改变。
关于 &A
中实际存储的内容:这有点复杂。您需要查看 C++ 安装中的头文件 vector
。或者看看 webpage for std::vector at cppreference.com 可能会更好。请注意,有很多模板,一些 subclassing,以及一些明确的模板特化,所以就像我说的 - 复杂。您可能需要重新考虑您是否 真的 想深入了解这个容器作为一般规则是如何工作的,或者 class' public 方法和 sizeof()
这个数字现在已经足够了。
how much information (or which information) about the vector is stored in the address
&A
您假设向量的数据与向量对象本身分开存储是正确的 - 通常在动态内存中。
矢量对象本身需要知道的三件事是
- 矢量数据的位置 - 我们需要它来执行
[]
运算符, - 当前分配的大小 - 我们需要它来知道何时增长数组,并且
- 实际放入向量中的元素数量 - 我们需要它来知道
push_back
的位置以及从 [=13] 到 return 的内容=].
不同的实现是可能的,在矢量对象本身中存储尽可能少的单个指针。然而,一个典型的实现存储了一个指向分配块开始的指针,一个指向分配块活动部分末尾的指针,以及一个指向分配块末尾的指针。
我是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
那么,我们可以得出结论,vector只是保留了一个指针,所以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