为啥 std::stack 内存大小比 C++ 中的通常大?

Posted

技术标签:

【中文标题】为啥 std::stack 内存大小比 C++ 中的通常大?【英文标题】:Why std::stack memory size is bigger than as usual in c++?为什么 std::stack 内存大小比 C++ 中的通常大? 【发布时间】:2021-04-05 09:10:26 【问题描述】:

这是测试我的问题的代码。

#include <iostream>
#include <stack>
using namespace std;
int main()
    int num;
    int Array[1];
    stack<int> Stack;

    cout << "Int size " << sizeof(num) <<endl; // Output: Int size 4
    cout << "Array size " << sizeof(num) <<endl; // Output: Array size 4
    cout << "Stack size " << sizeof(Stack) <<endl; // Output: Stack size 80
    return 0;

我正在尝试了解内存空间分配。通常 int 内存大小为 4 个字节。但是,当我在 std::stack 中初始化 int 数据类型的 Stack 时,Stack 的大小为 80 个字节。

应该是 4 吗?为什么std::stack 占用 80 个字节?或者堆栈内部实际上是 80 字节的大小?

【问题讨论】:

你使用的是什么编译器/标准库? @AyxanHaqverdili GNU GCC 编译器 std::stack 是一个类。类对象本身使用一些内存。 @JohnnyMopp 我也在课堂上进行了测试。类大小为 1 个字节。我认为堆栈包含占用 80 个字节的内容。问题是堆栈中实际占用 80 个字节的内容是什么? 一些常用集合使用的空间比较:ideone.com/f7sfcK 【参考方案1】:

sizeof 获取对象/类型的静态大小。 stack 为其元素动态分配内存。因此,元素的大小和stack 的大小通常没有相关性。那么,为什么是 80 字节呢?这是高度实现特定的。堆栈的大小通常与底层容器相同。默认情况下,底层容器是std::deque,所以我们必须看看。我专门检查了 libstdc++,它似乎有 1 个指针、1 个 size_t 的大小和 2 个迭代器,如下所示:

struct _Deque_impl_data

    _Map_pointer _M_map;
    size_t _M_map_size;
    iterator _M_start;
    iterator _M_finish;
    //...

std::deque 派生自 _Deque_base,它有一个 _Deque_impl_data 类型的成员)

指针和整数是 8 个字节,迭代器是 32 个字节。这增加了 80 个字节。我没有进一步调查,但由于deque 是一个更复杂的结构,它需要一些内存来自己记账是很自然的。

【讨论】:

【参考方案2】:

您可能在这里将sizeof(Stack)Stack.size() 混淆了。 sizeof 运算符返回 类对象 的总大小,在 std::stack 的情况下,它包括(必要的)一些内部数据和控制变量(将大小填充到,在你的情况下,80字节)。然而,对Stack.size() 的调用将返回当前在堆栈中的项数

这些“内部变量”将包括诸如指向已分配内存的指针(可能是 8 个字节)、一个记录当前元素计数的值(也可能是 8 个字节)以及许多其他指针和计数器,以帮助操作堆栈和优化对包含数据的访问,例如分配空间的当前容量等。

以下修改后的代码显示了区别:

#include <iostream>
#include <stack>
using namespace std;
int main()

    int num;
    int Array[1];
    stack<int> Stack;

    cout << "Int size " << sizeof(num) << endl;     // Int size 4
    cout << "Array size " << sizeof(Array) << endl; // Array size 4 (1 "int" element)
    cout << "Stack size " << sizeof(Stack) << endl; // Size of a "std::stack<int>" instance
    cout << "Stack size " << Stack.size() << endl;  // Size (# entries) of stack = 0 (empty)
    return 0;

【讨论】:

不,我不困惑。我知道Stack.size(); 将返回堆栈大小。因为我提到我试图了解内存空间。 @Naiem 好的,很抱歉假设您的困惑(但其他人已经犯了这个错误)。也许我的编辑给出了一些提示——尽管stack 类的实际细节会因实现而异。

以上是关于为啥 std::stack 内存大小比 C++ 中的通常大?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我的 Java 堆转储大小比已用内存小得多?

为啥我可以使用 POSIX 创建比 /dev/shm 上安装的大小更大的共享内存?

将元素从 std::vector 复制到 std::stack c++

为啥在这段代码中向量比指针使用更少的内存?

std::vector 与 std::stack

为啥 C++ 分配器中没有重新分配功能?