C++ 类对象的总内存 [英] total memory of a C++ class object
问题描述
为什么下面这段代码给出了 24 作为答案?即后面的类X的对象总大小是多少,24个字节?我使用的是 64 位机器.
#include 使用命名空间标准;X级{矢量 <bool>F;国际b;民众:X(){f.push_back(true);}};int main(){X ob;cout<
也就是下面X类的对象总大小是多少,24字节?我使用的是 64 位机器.
C++ 几乎不保证类型大小,也不保证标准容器的内存布局.因此,对于此类问题,说明您的编译器和调用它的选项也很重要.
<块引用>class X{矢量 <bool>F;国际b;民众:X(){f.push_back(true);}};
您可以查看 sizeof(int)
和 sizeof(vector
的单独结果.他们可能会透露以下信息:
int b
的 8 个字节.- 16 个字节用于
vector
.f
vector
的 16 个字节更难分析.一些东西可以存储在对象中,例如:
std::allocator
的一个实例,您在构造向量时不可见"地通过默认参数传递该实例.- 指向由数据占用的动态分配内存开始的指针,用于表示向量的
bool
元素. - 指向该内存末尾的指针(用于恒定时间
capacity()
调用). - 指向动态分配内存中最后一个元素的指针(用于恒定时间
size()
调用). - 当前元素计数或当前容量计数(对于恒定时间
size
和capacity()
调用).
如果您想确定,您可以查看您的实现的头文件,以了解您的编译器如何在内存中布置 std::vector
.
请注意,std::vector
的内存布局可能与所有其他 std::vector
不同,因为
如您所见,这里的 sizeof(std::vector
来自 sizeof(unsigned int*)
的三倍,用于指向第一个元素的指针,最后一个元素和容量在动态分配的内存中结束,加上一个额外的 sizeof(unsigned int)
用于元素计数,由于上述对 std::vector
,这意味着计算指向第一个和最后一个元素的指针之间的差异不一定会向外部代码显示向量代表的元素数量.
std::vector
不需要那种特殊处理,这就解释了为什么它更小.
由于空基优化.
<小时>考虑到所有因素,这都是非常复杂的事情.但这就是标准库实现者的世界!请记住,您在头文件中看到的所有内容都是严格内部的.例如,您不能以任何方式假设您自己的代码中存在 std::_Container_base0
.假装它不存在.
回到你最初的问题,最重要的一点是你的编译器可以以任何它想要的方式布置 std::vector
只要它对根据 C++ 标准的外部世界.它也可以选择根本不优化 std::vector
.如果不了解有关您的编译器的更多信息,我们无法告诉您更多信息.它在 64 位机器上运行的信息是不够的.
[*] std::vector
应该是一种节省空间的优化,但显然在这个实现中这只与空间有关被动态分配的元素占用,而不是向量本身的静态大小.
Why does the following piece of code gives 24 as an answer? That is, how is the total size of the object of following class X, 24 bytes? I'm using 64-bit machine.
#include <bits/stdc++.h>
using namespace std;
class X
{
vector <bool> f;
int b;
public:
X(){
f.push_back(true);
}
};
int main(){
X ob;
cout<<sizeof(ob);
return 0;
}
That is, how is the total size of the object of following class X, 24 bytes? I'm using 64-bit machine.
C++ makes few guarantees about type sizes and none about the memory layout of standard containers. For questions like this, it is therefore also important to state your compiler and the options with which you invoke it.
class X { vector <bool> f; int b; public: X(){ f.push_back(true); } };
You can look at the individual results for sizeof(int)
and sizeof(vector<bool>)
. They will probably reveal the following:
- 8 bytes for
int b
. - 16 bytes for
vector<bool> f
.
The 16 bytes for vector<bool>
are harder to analyse. Several things could be stored in the object, for example:
- An instance of the
std::allocator<bool>
that you "invisibly" pass via a default argument when you construct the vector. - A pointer to the start of the dynamically allocated memory occupied by the data to represent the vector's
bool
elements. - A pointer to the end of that memory (for constant-time
capacity()
calls). - A pointer to the last element inside that dynamically allocated memory (for constant-time
size()
calls). - The current element count or the current capacity count (for constant-time
size
andcapacity()
calls).
If you want to know for sure, you can probably look into your implementation's header files to see how your compiler lays out std::vector<bool>
in memory.
Note that the memory layout for a std::vector<bool>
can be different from all other std::vector
s due to special optimisations. For example, on my machine with MSVC 2013, compiled simply with cl /EHsc /Za /W4 stackoverflow.cpp
, sizeof(std::vector<bool>)
is 16 whereas sizeof(std::vector<int>)
is 12 [*].
Since header files internal to the implementation can be quite hard to read, an alternative way is to run your program in a debugger and inspect the object there. Here's an example screenshot from Visual Studio Express 2013:
As you can see, the sizeof(std::vector<bool>)
here comes from three times sizeof(unsigned int*)
for pointers to first element, last element and capacity end in the dynamically allocated memory, plus one extra sizeof(unsigned int)
for the element count, which is necessary due to the aforementioned special optimisation for std::vector<bool>
, which means that calculating the difference between the pointers to first and last element may not necessarily reveal the number of elements that the vector represents to outside code.
std::vector<int>
does not need that special handling, which explains why it's smaller.
The inherited std::_Container_base0
is apparently not taken into account due to Empty base optimization.
All things considered, this is all quite complicated stuff. But such is the world of standard-library implementors! Remember that all things you see inside of header files are strictly internal. You cannot, for example, suppose the existence of std::_Container_base0
in your own code in any way. Pretend that it does not exist.
Coming back to your original question, the most important point is that your compiler may lay out a std::vector<bool>
in any way it wants to as long as it behaves correctly to the outside world according to the C++ standard. It may also choose not to optimise std::vector<bool>
at all. We cannot tell you much more without knowing more about your compiler. The information that it runs on a 64-bit machine is not enough.
[*] std::vector<bool>
is supposed to be a space-efficient optimisation, but apparently in this implementation this only relates to space occupied by the dynamically allocated elements, not the static size of the vector itself.
这篇关于C++ 类对象的总内存的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!