C ++: Каков размер объекта пустого класса? - PullRequest
100 голосов
/ 07 марта 2009

Мне было интересно, что может быть размер объекта пустого класса . Это, безусловно, может , а не быть 0 байтов, поскольку должна быть возможность ссылаться и указывать на него, как и любой другой объект. Но насколько велик такой объект?

Я использовал эту маленькую программу:

#include <iostream>
using namespace std;

class Empty {};

int main()
{
    Empty e;
    cerr << sizeof(e) << endl;
    return 0;
}

Вывод, который я получил на компиляторах Visual C ++ и Cygwin-g ++, был 1 байт ! Это было немного удивительно для меня, так как я ожидал, что оно будет иметь размер машинного слова (32 бита или 4 байта).

Может кто-нибудь объяснить почему размер 1 байт? Почему бы не 4 байта? Это зависит от компилятора или машины тоже? Кроме того, может ли кто-нибудь дать более убедительную причину того, почему пустой объект класса не будет иметь размер 0 байт?

Ответы [ 16 ]

119 голосов
/ 07 марта 2009

Цитата Часто задаваемые вопросы Бьярна Страуструпа по стилю и технике C ++ , причина, по которой размер не равен нулю, заключается в том, чтобы "гарантировать, что адреса двух разных объектов будут разными". И размер может быть 1, потому что выравнивание здесь не имеет значения, так как на самом деле смотреть не на что.

30 голосов
/ 07 марта 2009

Стандарт гласит, что все наиболее производные объекты имеют sizeof ()> = 1:

Если это не битовое поле (class.bit), наиболее производный объект должен иметь ненулевой размер и занимать один или несколько байтов памяти. Подобъекты базового класса могут иметь нулевой размер. ISO / IEC FDIS 14882: 1998 (E) intro.object

12 голосов
/ 07 марта 2009

Это действительно деталь реализации. Когда-то давно я думал, что это может быть ноль или тысяча байтов, что это не имеет отношения к спецификации языка. Но, посмотрев на стандарт (раздел 5.3.3), sizeof определяется как всегда возвращающий один или более, несмотря ни на что.

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

Это необходимо, помимо прочего, для того, чтобы вы могли обрабатывать массивы объектов и указатели на них. Если бы вашим элементам было разрешено иметь нулевой размер, то &(array[0]) было бы идентично &(array[42]), что приведет к разного рода разрушениям в ваших циклах обработки.

Причина, по которой это может быть не машинное слово, заключается в том, что в нем нет элементов, которые фактически требуют его выравнивания по границе слова (например, целое число). Например, если вы поместите char x; int y; внутри класса, мой GCC синхронизирует его с восемью байтами (так как второй int должен быть выровнен в этой реализации).

6 голосов
/ 27 декабря 2012

Исключение: массивы 0-длины

#include <iostream>

class CompletlyEmpty {
  char NO_DATA[0];
};

int main(int argc, const char** argv) {
  std::cout << sizeof(CompletlyEmpty) << '\n';
}
5 голосов
/ 06 декабря 2012

Несмотря на то, что не требуется выделять какую-либо память для пустого класса, но для создания объектов из пустых классов компилятор назначает минимальный объем памяти, который можно назначить, который составляет 1 байт. Таким образом, компилятор может уникальным образом различать два объекта одного и того же пустого класса и назначать адрес объекта указателю пустого типа класса.

4 голосов
/ 08 марта 2009

Я думаю, что было бы полезно дать ссылку на ответ, объясняющий это тоже хорошо. Это о boost::compressed_pair Логан Капальдо .

3 голосов
/ 04 декабря 2011

Это может помочь вам :-) http://bytes.com/topic/c/insights/660463-sizeof-empty-class-structure-1-a

Размер пустого класса или структуры составляет 1

Причина, по которой это происходит, сводится к правильной реализации стандарт, одна из вещей, которые стандарт C ++ говорит, что «нет объекта должен иметь тот же адрес в памяти, что и любая другая переменная ".... Что самый простой способ обеспечить это? Убедитесь, что все типы имеют ненулевой размер. Для этого компилятор добавляет фиктивный байт к структурам и классам, которые не имеют членов данных и не виртуальные функции, так что они имеют размер 1, а не размер 0 и тогда они гарантированно будут иметь уникальный адрес памяти.

2 голосов
/ 04 ноября 2010

причина, по которой класс не содержит членов данных, но имеет размер 1 байт, заключается в том, что этот * строгий текст * должен храниться в памяти, чтобы ссылка или указатель могли указывать на объект этого класса

2 голосов
/ 05 мая 2010

Выделение 1 байта для пустого класса зависит от компилятора. Компиляторы должны убедиться, что объекты находятся в разных местах памяти, и им необходимо выделить ненулевой объем памяти для объекта. Слушайте заметки на эту тему здесь: http://listenvoice.com/listenVoiceNote.aspx?id=27

Несмотря на то, что компиляторы выделяют ненулевой размер пустому классу, они также проводят оптимизацию, когда новые классы получены из пустых классов. Послушайте, как оптимизировать пустую базу, на вопросы интервью по программированию на С ++ в ListenVoice.

0 голосов
/ 21 июля 2017

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...