我正在研究std::vectorlibc ++ 中的实现,我注意到它内部保留了三个指针(一个指向开头,一个结束,一个指向已分配内存的末尾),而不是我本能地做的,即,一个指针开始和两个size和capacity成员.
这是来自libc ++的代码<vector>(忽略压缩对,我知道它意味着什么).
pointer __begin_;
pointer __end_;
__compressed_pair<pointer, allocator_type> __end_cap_;
Run Code Online (Sandbox Code Playgroud)
我注意到其他标准库也做同样的事情(例如Visual C++).我没有看到为什么这个解决方案应该比另一个解决方案更快的任何特殊原因,但我可能是错的.
那么"三指针"解决方案是否优于"指针+尺寸"解决方案?
我尝试打印向量中元素的字节数和内存地址。结果,我看到了一个内存地址和多个字节。向量的元素是单独存储的吗?如果是这样,为什么我的代码显示向量只有 24 个字节?
#include <iostream>
#include <vector>
int main(){
std::vector<const char *> colour = {"Microsoft", "Apple", "DELL", "Accer", "Lenovo", "hp"};
std::cout << "VectorSize : " << sizeof(colour) << "\n" << std::endl;
for(int i = 0; i < colour.size(); i++){
std::cout << colour[i] << " is " << sizeof(colour[i]) << " byte at " << &colour[i] << "." << std::endl;
}
}
Run Code Online (Sandbox Code Playgroud)
VectorSize : 24
Microsoft is 8 byte at 0x27b5a7c6220.
Apple is 8 byte at …Run Code Online (Sandbox Code Playgroud) 我在理解这个汇编代码的作用时遇到了问题(这是一个较大的汇编代码,这是Intel语法):
vector<int> func(int i) { ...} // C++ source
Run Code Online (Sandbox Code Playgroud)
来自Godbolt编译器资源管理器的 clang输出:
func(int): # @func(int)
push rbp
push rbx
push rax
mov ebp, esi
mov rbx, rdi
xorps xmm0, xmm0
movups xmmword ptr [rbx], xmm0
mov qword ptr [rbx + 16], 0
Run Code Online (Sandbox Code Playgroud)
这是在Linux上编译的,遵循官方的System V AMD64 ABI.根据此链接,rdi寄存器用于将第一个参数传递给函数.所以在这条线上
mov rbx, rdi
Run Code Online (Sandbox Code Playgroud)
我们将参数的值(在本例中为int)移动到rbx.不久之后,我们做到:
movups xmmword ptr [rbx], xmm0
Run Code Online (Sandbox Code Playgroud)
这是我不明白的.rbx包含参数的值,它是一个int,这里我们将xmm0的内容复制到rbx指向的地址(但是rbx不包含任何地址,只是函数的参数!)
有些事我错了,但我无法弄明白为什么.
我正在阅读这篇C++参考资料,发现使用vector :: size()会在常量时间内返回向量的大小.但是,我想知道如何在不实际遍历矢量的情况下获得大小.
我想了解使用make([]int, 0). 我做这个代码进行测试:
emptySlice := make([]int, 0)
fmt.Println(len(emptySlice))
fmt.Println(cap(emptySlice))
fmt.Println(unsafe.Sizeof(emptySlice))
Run Code Online (Sandbox Code Playgroud)
size和容量返回很明显,都是0,但是slice的大小是24字节,为什么呢?
24 个字节应该是 3 个int64吧?一个包含 24 个字节的切片的内部数组应该类似于:[3]int{},那么为什么一个空切片有 24 个字节呢?