问题
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
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.
回答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