C ++类对象的总内存 [英] total memory of a C++ class object

查看:198
本文介绍了C ++类对象的总内存的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为什么下面的代码给出24作为答案?也就是说,下面的X,24字节的对象的总大小是多少?我使用的是64位机器。

  #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;
}


解决方案


也就是说,下面的类X的对象的总大小是多少,24
字节?我使用64位机器。


C ++对标准容器的内存布局没有提供类型大小的保证。对于这样的问题,因此,也必须声明你的编译器和调用它的选项。


  class X 
{
vector< bool> F;
int b;
public:
X(){
f.push_back(true);
}
};


您可以查看 sizeof(int) sizeof(vector< bool>)。他们会可能显示以下内容:

$




  • c $ c>。

  • 16个字节用于向量< bool> f 。

$ b 的16个字节更难分析。可以在对象中存储几个事物,例如:





  • 指向动态启动的指针,该指针指向动态启动的动态启动的指针。> std :: allocator< bool> 分配的数据占用的内存来表示向量的 bool 元素。

  • 指向内存结尾的指针 capacity()调用)。

  • 指向动态分配的内存中最后一个元素的指针c> size()调用)。

  • 当前元素计数或当前容量计数c $ c>和 capacity()调用)。



一定要知道,你可以看看你的实现的头文件,看看你的编译器如何在内存中展开 std :: vector< bool>



请注意, std :: vector< bool> 的内存布局可能不同于所有其他 std: :向量由于



正如你所看到的, sizeof std :: vector< bool>)这里来自三个 sizeof(unsigned int *)用于指向第一个元素,在动态分配的内存中,为元素计数加上一个额外的 sizeof(unsigned int),这是由于上述对 std的特殊优化所必需的: :vector< bool> ,这意味着计算指向第一和最后一个元素的指针之间的差异可能不一定显示向量表示到外部代码的元素的数量。



std :: vector< int> 不需要特殊处理, p>

继承的 std :: _ Container_base0 显然不会被考虑,因为空基本优化






所有的事情,这是所有相当复杂的东西。但是这是标准库实现者的世界!记住,你在头文件中看到的所有内容都是内部的。例如,您不能以任何方式假设您自己的代码中存在 std :: _ Container_base0



回到你原来的问题,最重要的一点是你的编译器可能会布局一个 std ::向量< bool> 以任何方式想要,只要它根据C ++标准正确地行为到外部世界。它也可以选择不优化 std :: vector< bool> 。我们不能告诉你更多不了解你的编译器。它在64位计算机上运行的信息是不够的。






[*] std :: vector< bool> 应该是一个节省空间的优化,但显然在这个实现中,这只涉及动态分配的元素,而不是向量本身的静态大小。


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 and capacity() 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::vectors 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆