total memory of a C++ class object

可紊 提交于 2019-12-24 11:53:46

问题


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

回答1:


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.




回答2:


vector maintains its own internal variables for book keeping and also allocator.

Factor in the size of int on your machine added to the size of vector and you have the sum total.

Note:

with regards to int, size of a pointer should be 8 byte on any 64-bit C/C++ compiler, but not necessarily size of int.

you can see the internals of vector(for gcc) here for a quick lookup: https://gcc.gnu.org/onlinedocs/gcc-4.6.3/libstdc++/api/a01115_source.html



来源:https://stackoverflow.com/questions/32931360/total-memory-of-a-c-class-object

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!