【问题标题】:Why does a bool appear to take up as much memory as an int? C++为什么 bool 似乎占用与 int 一样多的内存? C++
【发布时间】:2013-11-21 09:21:50
【问题描述】:

当我在 dev cpp 上运行这个程序时,任务管理器说它大约有 79 MB。使用 gnu c++ 4.7 的 Codeforces 说它是 79112 KB

#include<stdio.h>
const int N=10010,K=1010;
struct TPos
{
    int charge;
    bool ex;
    TPos()
    {
        charge=1<<30;
        ex=false;    
    }  
};
TPos d[N][K];

int main()
{
    while(1);
    return 0;
}

但是当 ex 参数被注释时:

#include<stdio.h>
const int N=10010,K=1010;
struct TPos
{
    int charge;
    //bool ex;
    TPos()
    {
        charge=1<<30;
        //ex=false;    
    }  
};
TPos d[N][K];

int main()
{
    //while(1);
    return 0;
}

只有 39536 KB。 我认为布尔值应该使用一个字节。为什么要翻倍?

【问题讨论】:

  • 您可以尝试 __attribute__((packed)) 看看它的外观(但这通常不是提高性能的好习惯)
  • 如果您不需要 charge 的所有 int 位,您甚至可以将内存需求减少到 sizeof(int)。请看下面我的回答。 (也许一个或多或少的 2 的功率并没有太大的区别。)

标签: c++ memory boolean


【解决方案1】:

除非你打包一个结构,否则它总是占用可被字长整除的内存(因为内存对齐)。例如,您可以在 gcc 中使用 __attribute__(packed) 打包结构。另见here。打包结构可能会减少所需的内存,但几乎肯定会减慢执行速度。

【讨论】:

【解决方案2】:

Bool 是一个字节,但您在这里看到的是结构打包。

您的结构包含一个 int,因此编译器会自动将结构与 int 的大小对齐,以确保它在数组中得到正确对齐。否则,数组的第二个元素的 int 会出现在不正确对齐的地址上 - 这可能会导致性能下降,在某些架构上甚至会导致崩溃。

您可以使用特定于编译器的编译指示和属性显式关闭结构打包,但您不想这样做。如果内存是一个问题,请考虑使用数组结构而不是结构数组。

【讨论】:

    【解决方案3】:

    因为内存对齐。在这种情况下,boolstructint 中对齐。含义 - 有一些额外未使用的字节。

    这意味着,sizeof( your_struct ) 会给你2 * sizeof( int )

    您可以对此进行一些实验 - 检查 sizeofstructure,其中包含更多 bools(一个接一个),通过重新排序元素再次检查大小等。这些是有用的实验来了解会发生什么。此外,对结构填充和内存对齐的研究对您非常有用。

    【讨论】:

      【解决方案4】:

      它与结构对齐有关。在某些平台上,如果它是 4 字节的倍数,则更容易寻址内存。编译器可能会填充您的结构以使其更易于使用。 如果我是正确的,您可以添加另一个 bool,您将看到没有使用额外的空间。

      检查编译器选项以了解如何禁用它,但请注意性能可能会受到影响。

      【讨论】:

        【解决方案5】:

        确实bool 通常使用一个字节(但它不是必须的)。

        不过,C 和 C++ 也允许在结构中添加 padding(即空白)以允许对齐。这有点复杂,但基本上当变量在特定边界上对齐时,内存访问会变得更快。

        在这种情况下,添加额外的 bool 可能会将结构大小从 4 个字节(仅在 int 中)增加到 8 个字节,因此允许结构在数组中很好地对齐。这当然取决于你的编译器,但你可以使用sizeof(TPos) 来检查。

        大多数编译器都有扩展来请求不填充特定结构,即使这会使它们使用起来更慢——你可能想研究一下。

        【讨论】:

          【解决方案6】:

          您可以使用大小说明符来减小对象的大小(请参阅以下代码中的:)。如果您真的不需要 charge 的完整 int 大小,这可能看起来像 TPosB

          #include <iostream>
          
          #include<stdio.h>
          struct TPosB
          {
              int charge : sizeof(int)-1;
              bool ex : 1;
              TPosB()
              {
                  charge=1 << sizeof(int)-2;
                  ex=false;
              }
          };
          TPosB b;
          
          struct TPos
          {
              int charge;
              bool ex;
              TPos()
              {
                  charge=1<<30;
                  ex=false;    
              }  
          };
          TPos a;
          
          int main()
          {
              std::cout << "sizeof(int)" << sizeof(int);
              std::cout << "\nsizeof(a)=" << sizeof(a);
              std::cout << "\nsizeof(b)=" << sizeof(b);
          
              return 0;
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2020-10-25
            • 2023-03-05
            • 2021-07-13
            • 1970-01-01
            • 2020-10-21
            • 1970-01-01
            • 2018-11-08
            相关资源
            最近更新 更多