我正在为正确的心理模式和对精神病的理解而挣扎std::vector。
当创建类型T的向量,然后为该向量保留N个元素时,编译器基本上会找到并保留一个连续的内存块,即N * sizeof(T)字节。例如,
// Initialize a vector of int
std::vector<int> intvec;
// Reserve contigious block of 4 4-byte chunks of memory
intvec.reserve(4); // [ | | | ]
// Filling in the memory chunks has obvious behavior:
intvec.push_back(1); // [1| | | ]
intvec.push_back(2); // [1|2| | ]
Run Code Online (Sandbox Code Playgroud)
然后,我们可以在随机访问时间内访问任何元素,因为如果我们要求向量的第k个元素,我们只需从向量的开始处的内存地址开始,然后“跳转” k * sizeof(T)字节以获取第k个元素。
我的思维模型针对大小未知/不同的自定义对象进行了分解。例如,
class Foo {
public:
Foo() = default;
Foo(std::vector<int> vec): _vec{vec} {}
private:
std::vector<int> _vec;
};
int main() {
// Initialize a vector Foo
std::vector<Foo> foovec;
// Reserve contigious block of 4 ?-byte chunks of memory
foovec.reserve(4); // [ | | | ]
// How does memory allocation work since object sizes are unkown?
foovec.emplace_back(std::vector<int> {1,2}); // [{1,2}| | | ]
foovec.emplace_back(std::vector<int> {1,2,3,4,5}); // [{1,2}|{1,2,3,4,5}| | ]
return 0;
}
Run Code Online (Sandbox Code Playgroud)
由于我们不知道每个Foo实例的大小,如何foovec.reserve()分配内存?此外,您如何获得随机访问时间,而我们不知道要“跳”多远才能到达第k个元素?
Nat*_*ica 11
Your concept of size is flawed. A std::vector<type> has a compile time known size of space it is going to take up. It also has a run time size that it may use (this is allocated at run time and the vector holds a pointer to it). You can picture it laid out like
+--------+
| |
| Vector |
| |
| |
+--------+
|
|
v
+-------------------------------------------------+
| | | | | |
| Element | Element | Element | Element | Element |
| | | | | |
+-------------------------------------------------+
Run Code Online (Sandbox Code Playgroud)
So when you have a vector of things that have a vector in them, each Element becomes the vector and then those point of to their own storage somewhere else like
+--------+
| |
| Vector |
| |
| |
+----+---+
|
|
v
+----+----+---------+---------+
| Object | Object | Object |
| with | with | with |
| Vector | Vector | Vector |
+----+----+----+----+----+----+
| | | +---------+---------+---------+---------+---------+
| | | | | | | | |
| | +-->+ Element | Element | Element | Element | Element |
| | | | | | | |
| | +-------------------------------------------------+
| | +-------------------------------------------------+
| | | | | | | |
| +--->+ Element | Element | Element | Element | Element |
| | | | | | |
| +-------------------------------------------------+
| +-------------------------------------------------+
| | | | | | |
+--->+ Element | Element | Element | Element | Element |
| | | | | |
+---------+---------+---------+---------+---------+
Run Code Online (Sandbox Code Playgroud)
This way all of the vectors are next to each other, but the elements the vectors have can be anywhere else in memory. It is for this reason you don't want to use a std:vector<std::vector<int>> for a matrix. All of the sub vectors get memory to wherever so there is no locality between the rows.
Do note that this applies to all of the allocator aware containers as they do not store the elements inside the container directly. This is not true for std::array as, like a raw array, the elements are part of the container. If you have an std::array<int, 20> then it is at least sizeof(int) * 20 bytes in size.
的大小
class Foo {
public:
Foo() = default;
Foo(std::vector<int> vec): _vec{vec} {}
private:
std::vector<int> _vec;
};
Run Code Online (Sandbox Code Playgroud)
已知且常量,内部std :: vector在堆中进行分配,因此没有问题foovec.reserve(4);
否则std :: vector怎么会在堆栈中?;-)
| 归档时间: |
|
| 查看次数: |
139 次 |
| 最近记录: |