为什么当我向一个向量中添加元素时,它的大小是一样的?
Why does a vector have the same size when I add elements to it?
我有这样的c++结构:
typedef unsigned long T;
struct Node {
T index;
T length;
Node(): index(0), length(0), next(0) {}
Node(const T &ind, const T &len): index(ind), length(len), next(0) {}
vector<Node*> next;
};
我想知道下一个将占用多少内存。我知道它最多有五个元素。我是这样做的:
int main(int argc, const char * argv[]) {
Node n;
Node* x = new Node(3, 4);
cout << "An empty vector of pointers: " << sizeof(n.next) << " bytesn";
// Add five elements
for(int i = 0; i < 5; i++)
n.next.push_back(x);
cout<< "New size of the vector of pointers: " << n.next.size() << " elementsn";
cout<< "New size of the vector of pointers: " << sizeof(n.next) << " bytesn";
return 0;
}
下面是我的输出:
An empty vector of pointers: 24 bytes
New size of the vector of pointers: 5 elements
New size of the vector of pointers: 24 bytes
我的问题:怎么可能一个空向量需要24个字节,但相同的向量有5个元素在它仍然需要24个字节?它不应该占用更多的内存吗?像*24 + 5 * sizeof(Node*)*?
Vector是一个动态结构体,具有固定的"footprint",通常包含指向动态分配数据的指针。
n.next.size()
返回动态分配数据的大小。sizeof(n.next)
返回固定占用空间的大小。
给定类型的所有对象大小相同,sizeof(n.next)
与sizeof(vector<Node*>)
等效。
vector
实例不包含元素,它只指向它们,所以实例本身总是相同的大小。
它的工作原理是这样的:
class A
{
public:
A(int n) : p(new char[n]), s(n) {}
int size() const { return s; }
private:
char* p;
int s;
};
int main()
{
A a(1);
A b(100);
// These all print the same thing:
std::cout << sizeof(a);
std::cout << sizeof(b);
std::cout << sizeof(A);
// These are different:
std::cout << a.size(); // Prints 1
std::cout << b.size(); // Prints 100
}
如果你想知道你的向量总共占用了多少空间,你需要自己计算。
你想要n.next.size()
。
sizeof
完全是一个编译时操作,因为它只是查看类型来计算存储它的一个实例需要多少字节。sizeof(n.next)
告诉您保存n.next
需要多少字节。因为它是一个vector
,它很可能使用3个指针(每个8字节)来实现——一个指向已分配数组的开始,一个指向数据的结束,一个指向已分配数组的结束。
作为标准的矢量实现通常被优化为在其生命周期开始时拥有比必要的空间量更多的空间。简单地说,即使您要求的对象较少,该实现也会在8个对象上为vector规划空间,并且只有在超过这个数量后才开始分配更多的内存。
如果你从不使用这些元素,这会浪费一些内存,但是会消除为你添加的每个元素重新分配内存的性能开销。确切的数量取决于实现,有些可能不会这样做,但这是一个典型的优化。
如果你想测量一个元素占用的空间,你需要更大的量;例如,放入100个物体并检查,然后放入200个物体并检查。对于较小的量,您将看到一个固定的大小,直到达到阈值。
- 将成员变量添加到共享库中的类中,不会破坏二进制兼容性吗
- 如何在C++中从两个单独的for循环中添加两个数组
- POCO::PostgreSQL:如何将std::vector支持添加到`Binder::bind`
- 如何仅为一个函数添加延迟
- 如何防止 c++ 在从浮点型转换为双精度型(不适用于 IO)时添加额外的小数?
- 使用std::transform将一个范围的元素添加到另一个范围中
- 如何将更多文件夹添加到c++include路径
- 如何将元素添加到数组的线程安全函数?
- QT通过C++添加映射QML项目
- 如何将点击的信号和插槽添加到qt中的自定义按钮中
- 如何使用重载的相等(==)运算符向测试用例添加描述
- 为什么Mat类的两个对象可以在不重载运算符+的情况下添加
- 如何防止clang格式在流运算符调用之间添加换行符<<
- 只能向C++添加一定数量的字符
- Qt和C++:将QLineEdit添加到QTabWidget中
- 如何在文件系统之上添加层?就像OneDrive或Google云端硬盘中的缓存一样
- 如何编写一个程序,我可以像 Ubuntu 中的命令一样添加信息(例如:程序 -u "Hello World" )
- 为什么队列的所有元素都是一样的,元素被添加到 posix 线程中的队列中
- 在 c# 中将 int 添加到字符以将其 ascii 值向上移动(就像在 c++ 中一样)
- 为什么当我向一个向量中添加元素时,它的大小是一样的?