C ++类对象的总内存

时间:2015-10-04 08:07:22

标签: c++ memory memory-management 64-bit

为什么下面这段代码会给出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;
}

2 个答案:

答案 0 :(得分:3)

  

也就是说,如何跟随类X的对象的总大小,24   字节?我使用的是64位机器。

C ++对类型大小几乎没有任何保证,也没有关于标准容器的内存布局的保证。对于这样的问题,因此说明编译器以及调用它的选项也很重要。

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

您可以查看sizeof(int)sizeof(vector<bool>)的个别结果。他们可能揭示以下内容:

  • int b的8个字节。
  • vector<bool> f的16个字节。

vector<bool>的16个字节难以分析。 可以存储在对象中的几件事情,例如:

  • {&#34;隐身&#34; std::allocator<bool>的一个实例在构造向量时通过默认参数传递。
  • 指向数据占用的动态分配内存开头的指针,用于表示向量的bool元素。
  • 指向该内存末尾的指针(用于常量capacity()调用)。
  • 指向动态分配内存中最后一个元素的指针(用于常量size()调用)。
  • 当前元素数或当前容量数(适用于固定时间sizecapacity()来电)。

如果您想确切知道,可以查看实现的头文件,看看编译器如何在内存中列出std::vector<bool>

请注意,由于special optimisationsstd::vector<bool>的内存布局可能与所有其他std::vector不同。例如,在我的MSVC 2013机器上,仅使用cl /EHsc /Za /W4 stackoverflow.cpp进行编译,sizeof(std::vector<bool>)为16,而sizeof(std::vector<int>)为12 [*]

由于实现内部的头文件很难读取,因此另一种方法是在调试器中运行程序并检查那里的对象。以下是Visual Studio Express 2013的示例屏幕截图:

Memory layout of <code>std::vector<bool></code> and <code>std::vector<int></code> in MSVC 2013

正如您所看到的,sizeof(std::vector<bool>)来自三次sizeof(unsigned int*)指向第一个元素,最后一个元素和容量在动态分配的内存中结束,另外还有一个sizeof(unsigned int)元素计数,由于上述std::vector<bool>的特殊优化而必需,这意味着计算指向第一个和最后一个元素的指针之间的差异可能不一定会显示向量表示的元素数量< / em>到外部代码。

std::vector<int>不需要那种特殊处理,这就解释了为什么它会变小。

由于Empty base optimization,显然没有考虑继承的std::_Container_base0

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

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

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

答案 1 :(得分:1)

vector维护自己的内部变量用于簿记和分配器。

计算机上int大小的因子会增加到向量的大小,并且总和为。

注意:

关于int,指针的大小在任何64位C / C ++编译器上都应该是8字节,但不一定是int的大小。

你可以在这里看到vector(for gcc)的内部结构,以便快速查找: https://gcc.gnu.org/onlinedocs/gcc-4.6.3/libstdc++/api/a01115_source.html