简体   繁体   English

为什么bool似乎占用了与int相同的内存? C ++

[英]Why does a bool appear to take up as much memory as an int? C++

When i run this program at dev cpp, task manager says that it's about 79 MB. 当我在dev cpp运行这个程序时,任务管理器说它大约是79 MB。 Codeforces with gnu c++ 4.7 says that it's 79112 kilobytes 使用gnu c ++ 4.7的代码表示它是79112千字节

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

But when ex parametr is commented: 但是当ex parametr被评论时:

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

it's only 39536 KB. 它只有39536 KB。 I thought that boolean should use one byte. 我认为布尔值应该使用一个字节。 Why does it double the size? 为什么它的尺寸加倍?

Unless you pack a structure it will always take memory that is divisable by the word size(because of the memory allignment). 除非你打包一个结构,否则它总是占用可被字大小分割的内存(因为内存对齐)。 You pack a structure by using __attribute__(packed) in gcc for example. 例如,在gcc中使用__attribute__(packed)结构。 See also here . 另见这里 Packing a structure may reduce the required memory but will almost certainly slow down the execution. 打包结构可能会减少所需的内存,但几乎肯定会减慢执行速度。

Bool is a byte, but what you're seeing here is structure packing. Bool是一个字节,但你在这里看到的是结构打包。

Your struct contains an int, so the compiler automatically aligns the structure to the size of an int to ensure that it's guaranteed to be properly aligned in an array. 您的struct包含一个int,因此编译器会自动将结构与int的大小对齐,以确保它保证在数组中正确对齐。 Otherwise, the second element of your array would have the int on an improperly aligned address - that could lead to decreased performance and on some architectures even to a crash. 否则,数组的第二个元素将在不正确对齐的地址上使用int - 这可能会导致性能下降,甚至导致某些体系结构崩溃。

You can explicitly turn structure packing off using compiler-specific pragmas and attributes, but you don't want to. 您可以使用特定于编译器的编译指示和属性显式关闭结构打包,但您不希望这样做。 If memory is a concern, consider using a struct of arrays instead of an array of structs. 如果需要关注内存,请考虑使用数组结构而不是结构数组。

Because of the memory alignment. 因为内存对齐。 In this case, the bool is aligned in the struct to int . 在这种情况下, boolstruct对齐为int Meaning - there are some extra unused bytes. 含义 - 有一些额外的未使用字节。

This means, sizeof( your_struct ) will give you 2 * sizeof( int ) . 这意味着, sizeof( your_struct )将为您提供2 * sizeof( int )

You can do some experiments with this - check the sizeof the struct ure with some more bool s inside it (one after the other), check the size again by reordering the elements, etc. These are useful experiments to understand what happens. 您可以对此进行一些实验 - 检查structsizeof ,其中包含更多的bool (一个接一个),通过重新排序元素再次检查大小等。这些都是有用的实验来了解会发生什么。 Also, research for struct padding and memory alignment would be extremely useful for you. 此外,对结构填充和内存对齐的研究对您非常有用。

It has to do with structure alignment. 它与结构对齐有关。 On some platforms it's easier to address memory if it's multiple of 4 bytes. 在某些平台上,如果内存是4个字节的倍数,则更容易解决内存问题。 The compiler might pad your structure to make it easier to work with. 编译器可能会填充您的结构以使其更易于使用。 If I'm correct you can add another bool and you will see no extra space used. 如果我是正确的你可以添加另一个bool,你会看到没有使用额外的空间。

Check compiler options on how to disable it, but note that the performance might suffer. 检查编译器选项如何禁用它,但请注意性能可能会受到影响。

It's true that bool usually uses one byte (it doesn't have to, though). 确实, bool通常使用一个字节(尽管如此)。

However, C and C++ are also allowed to add padding -- that is, empty space -- into structs to allow for alignment. 但是,C和C ++也允许将填充 (即空白空间)添加到结构中以允许对齐。 It's a bit complicated, but basically when variables are aligned on particular boundaries, then memory access becomes much quicker. 它有点复杂,但基本上当变量在特定边界上对齐时,内存访问变得更快。

In this case, adding the extra bool has probably increased the struct size from 4 bytes (for just in the int ) to 8 bytes, so allow the structs to be nicely aligned inside your array. 在这种情况下,添加额外的bool可能会将结构大小从4个字节(仅在int )增加到8个字节,因此允许结构在数组内很好地对齐。 This all depends on your compiler of course, but you can use sizeof(TPos) to check. 这当然取决于您的编译器,但您可以使用sizeof(TPos)进行检查。

Most compilers have extensions to request that a particular struct not be padded, even if this makes them slower to use -- you may want to look into this. 大多数编译器都有扩展来请求填充特定的结构,即使这使得它们使用起来更慢 - 你可能想要研究这个。

You can use the size specifier to reduce the size of your objects (See the : in the following code). 您可以使用尺寸说明,以减少你的对象的大小(请参阅:在下面的代码)。 If you do not really need the full int size for charge this could look like TPosB : 如果你真的不需要完整的int大小的charge这可能看起来像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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM