Размер байта объединения и структуры - PullRequest
0 голосов
/ 09 декабря 2018
 #include <iostream>
 using namespace std;
 typedef union {
            long i;
            int k[5];
            char c;
 } UDATE;
 struct data {
            int cat;
            UDATE cow;
            double dog;
  } too;
 UDATE temp;
 int main()
 {
        cout << sizeof(struct data)+sizeof(temp) << endl;
        return 0;
  }

в Ubuntu 18.04, ответ на этот вопрос 64, но я хочу знать, как uDATE корова в структуре хранится в памяти, или правила хранения данных?

1 Ответ

0 голосов
/ 09 декабря 2018

В соответствии со стандартом C ++:

Размер объединения достаточен, чтобы содержать самый большой из его элементов данных.Каждый элемент данных выделяется так, как если бы он был единственным членом структуры.

Таким образом, структура памяти объединения такая же, как если бы у вас был long, массив из 5 int s там или char там, но разнесены по наибольшим из них (массив int s).Я предполагаю, что вы используете GCC, и IIRC GCC устанавливает размер 32-битного для int даже на 64-битной архитектуре.Поэтому UDATE будет иметь размер 20 байтов.Поэтому вы наивно ожидаете, что sizeof(struct data) + sizeof(temp) вернет 52. Тот факт, что вы, очевидно, получаете 64, возможно, потому, что GCC выравнивает объекты по 64-битным границам и, таким образом, берет 24 байта для UDATE и вставляет 4-межбайтовый интервал между cat и cow в вашей data struct.

Обратите внимание, что в стандарте не дается никаких гарантий в отношении типов - это часто используемая техника низкого уровня, где объединение записывается с использованиемодин метод и чтение с использованием другого, например, для доступа к байтам, составляющим целое число, и утверждает, что объединение может быть доступно только с использованием тех же записей, которые были записаны с его использованием (исключая исключение для объединения структур POD, которые разделяютобщие начальные члены).Однако на практике каждый компилятор, который я когда-либо использовал, будет считывать память так, как вы ожидаете, если бы вы просто приводили указатель из одного типа в другой в объединении, используя переинтерпретацию или C-стиль исполнения.

...