Почему sizeof для структуры не равен сумме sizeof каждого члена?

Я не думаю, что вы можете сделать это через командную строку (возможно, не с некоторыми хаками bash), но вы определенно можете сделать это программно:

Просто установите одно свойство -DmyPropertiesFile=/your/properties/file.properties, а затем прочитайте что с одной из перегрузок Properties.load(). После этого System.setProperties(yourProps) должен делать то, что вы ожидаете.

Конечно, для этого требуется, чтобы вы могли перехватить этот код достаточно рано, чтобы ваши свойства были доступны по мере необходимости (например, если main() метод ваш, это прекрасно).

624
задан tilz0R 23 September 2018 в 09:09
поделиться

6 ответов

Это из-за дополнения добавленного для удовлетворения ограничений выравнивания. выравнивание Структуры данных влияние и производительность и правильность программ:

  • Неправильно выровненный доступ мог бы быть серьезной ошибкой (часто SIGBUS).
  • Неправильно выровненный доступ мог бы быть исправимой ошибкой.
    • Любой исправленный в аппаратных средствах, для скромного снижения производительности.
    • Или исправленный эмуляцией в программном обеспечении, для серьезного снижения производительности.
    • , Кроме того, атомарность и другие гарантии параллелизма могли бы быть повреждены, ведя к тонким ошибкам.

Вот пример с помощью типичных настроек для x86 процессора (все использовали режимы на 32 и 64 бита):

struct X
{
    short s; /* 2 bytes */
             /* 2 padding bytes */
    int   i; /* 4 bytes */
    char  c; /* 1 byte */
             /* 3 padding bytes */
};

struct Y
{
    int   i; /* 4 bytes */
    char  c; /* 1 byte */
             /* 1 padding byte */
    short s; /* 2 bytes */
};

struct Z
{
    int   i; /* 4 bytes */
    short s; /* 2 bytes */
    char  c; /* 1 byte */
             /* 1 padding byte */
};

const int sizeX = sizeof(struct X); /* = 12 */
const int sizeY = sizeof(struct Y); /* = 8 */
const int sizeZ = sizeof(struct Z); /* = 8 */

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

ВАЖНОЕ ПРИМЕЧАНИЕ: И C и стандарты C++ указывают, что выравнивание структуры определяется реализацией. Поэтому каждый компилятор может принять решение выровнять данные по-другому, приведя к различным и несовместимым форматам данных. Поэтому при контакте с библиотеками, которыми будут пользоваться различные компиляторы, важно понять, как компиляторы выравнивают данные. Некоторые компиляторы имеют настройки командной строки и/или особенный #pragma операторы для изменения настроек выравнивания структуры.

604
ответ дан 6 revs, 6 users 79% 23 September 2018 в 09:09
поделиться

Упаковка и выравнивание байта, как описано в C FAQ здесь :

Это для выравнивания. Много процессоров не могут получить доступ 2-и 4-байтовые количества (например, ints и длинные целые), если они переполнены в во все стороны.

предположим у Вас есть эта структура:

struct {
    char a[3];
    short int b;
    long int c;
    char d[3];
};

Теперь, Вы могли бы думать, что должно быть возможно упаковать эту структуру в память как это:

+-------+-------+-------+-------+
|           a           |   b   |
+-------+-------+-------+-------+
|   b   |           c           |
+-------+-------+-------+-------+
|   c   |           d           |
+-------+-------+-------+-------+

, Но очень, намного легче на процессоре, если компилятор располагает его как это:

+-------+-------+-------+
|           a           |
+-------+-------+-------+
|       b       |
+-------+-------+-------+-------+
|               c               |
+-------+-------+-------+-------+
|           d           |
+-------+-------+-------+

В упакованной версии, заметьте, как Вам и мне, по крайней мере, немного трудно видеть, как b и c поля повторяются? Короче говоря это трудно для процессора, также. Поэтому большинство компиляторов дополнит структуру (как будто с дополнительными, невидимыми полями) как это:

+-------+-------+-------+-------+
|           a           | pad1  |
+-------+-------+-------+-------+
|       b       |     pad2      |
+-------+-------+-------+-------+
|               c               |
+-------+-------+-------+-------+
|           d           | pad3  |
+-------+-------+-------+-------+
163
ответ дан Jamal 23 September 2018 в 09:09
поделиться

Если Вы хотите, чтобы структура имела определенный размер с GCC, например, используют __attribute__((packed)) .

В Windows можно установить выравнивание на один байт при использовании cl.exe compier с /Zp опция .

Обычно, для ЦП легче получить доступ к данным, которые являются кратными 4 (или 8), завися платформа и также на компиляторе.

, Таким образом, это - вопрос выравнивания в основном.

у Вас должны быть серьезные основания изменить его.

23
ответ дан 3 revs, 2 users 96% 23 September 2018 в 09:09
поделиться

Это может произойти из-за выравнивания байта и дополнения так, чтобы структура вышла к четному числу байтов (или слова) на Вашей платформе. Например, в C на Linux, следующих 3 структурах:

#include "stdio.h"


struct oneInt {
  int x;
};

struct twoInts {
  int x;
  int y;
};

struct someBits {
  int x:2;
  int y:6;
};


int main (int argc, char** argv) {
  printf("oneInt=%zu\n",sizeof(struct oneInt));
  printf("twoInts=%zu\n",sizeof(struct twoInts));
  printf("someBits=%zu\n",sizeof(struct someBits));
  return 0;
}

Имеют участников, кто размеры (в байтах), 4 байта (32 бита), 8 байтов (2x 32 бита) и 1 байт (2+6 битов) соответственно. Вышеупомянутая программа (на Linux с помощью gcc) печатает размеры как 4, 8, и 4 - где последняя структура дополняется так, чтобы это было отдельное слово (4 байта на 8 битов на моей платформе на 32 бита).

oneInt=4
twoInts=8
someBits=4
13
ответ дан Kyle Burton 23 September 2018 в 09:09
поделиться

Это может сделать так при неявно или явной установке выравнивания структуры. Структура, которая выравнивается 4, будет всегда кратной 4 байтам, даже если бы размер ее участников был бы чем-то, что это не несколько 4 байта.

Также библиотека может быть скомпилирована под x86 с 32-разрядным ints, и можно выдерживать сравнение, его компоненты на 64-разрядном процессе были бы давать Вам различный результат при выполнении этого вручную.

5
ответ дан Orion Adrian 23 September 2018 в 09:09
поделиться

В дополнение к другим ответам структура может (но обычно не делает), имеют виртуальные функции, в этом случае размер структуры будет также включать пространство для vtbl.

4
ответ дан JohnMcG 23 September 2018 в 09:09
поделиться