Структуры гигантские.Зачем? - PullRequest
0 голосов
/ 24 июня 2019

Я делаю грабеж Minecraft, и я использую структуру для хранения предметов, и только это:

typedef struct Item {
    union {
        struct {
            int V:4;
            int Q:6;
            int ID;
        } BItem;
        struct {
            union {
                struct {
                    int V:4;
                    int Q:6;
                    int ID;
                } BItem;
                struct {
                    int *Ench;
                    double Durability;
                    char *Name;
                    int ID;
                } TItem;
            } Item[4][8];
            enum {
                ICBItem,
                ICTItem
            } Type;
        } CItem;
        struct {
            int *Ench;
            double Durability;
            char *Name;
            int ID;
        } TItem;
    } ItemUnion;
    enum {
        BItem,
        CTtem,
        TItem
    } Type;
    void *UseHandler;
} Item;

Я использую sizeof и получаю 1024 байта. Просто это не должно занимать столько памяти. Может кто-нибудь объяснить? Я нахожу это очень расстраивающим, и я хочу сохранить это в файле как число, используя каким-то образом преобразование структуры в int с использованием memcpy, но НЕТ intager достаточно велик для массивной структуры.

1 Ответ

3 голосов
/ 24 июня 2019

Это

            } Item[4][8];

в 32 раза больше

            struct {
                int *Ench;
                double Durability;
                char *Name;
                int ID;

С указателем int на 8 байтов и двойным на 8 байтов и указателем char на 8 байтов и int на 4 байта и некоторым неизвестным заполнением для получения правильного выравнивания, которое может быть 32 байта. Таким образом, 4 x 8 x 32 составляют 1024 байта.

Попробуйте этот код:

int main()
{
    Item x;
    printf("%zu\n", sizeof x);
    printf("%zu\n", sizeof x.ItemUnion.CItem);
    printf("%zu\n", sizeof x.ItemUnion.CItem.Item);
    printf("%zu\n", sizeof x.ItemUnion.CItem.Item[0][0]);
    printf("%zu\n", sizeof x.ItemUnion.CItem.Item[0][0].TItem);

    printf("%p\n", (void*)&x.ItemUnion.CItem.Item[0][0].TItem.Ench);
    printf("%p\n", (void*)&x.ItemUnion.CItem.Item[0][0].TItem.Durability);
    printf("%p\n", (void*)&x.ItemUnion.CItem.Item[0][0].TItem.Name);
    printf("%p\n", (void*)&x.ItemUnion.CItem.Item[0][0].TItem.ID);
    printf("%p\n", (void*)&x.ItemUnion.CItem.Item[0][1].TItem.Ench);
    return 0;
}

На одной платформе я получаю:

1048
1032
1024
32
32
0x7ffcdec7ea90  // Ench
0x7ffcdec7ea98  // Durability - 8 bytes later so Ench takes 8 bytes
0x7ffcdec7eaa0  // Name - 8 bytes later so Durability takes 8 bytes
0x7ffcdec7eaa8  // ID - 8 bytes later so Name takes 8 bytes
0x7ffcdec7eab0  // Ench of next element - 8 bytes later so ID takes 8 bytes

Итак, у нас есть 4 х 8 байтов, что составляет 32 байта. Некоторые из них могут быть дополнением - наиболее вероятный идентификатор - это всего лишь 4 байта, за которыми следует заполнение 4 байта.

...