Каков размер пустого класса в C++, Java?

Каков размер пустого класса в C++ и Java? Почему это не ноль?sizeof(); возвращает 1 в случае C++.

8 ответов

Решение

Короткий ответ:

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

Длинный ответ:

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

Замечания:

Даже если объект имеет ненулевой размер, если он фактически занимает нулевое пространство, ему не нужно увеличивать размер производного класса:

Пример:

#include <iostream>

class A {};
class B {};
class C: public A, B {};

int main()
{
     std::cout << sizeof(A) << "\n";
     std::cout << sizeof(B) << "\n";
     std::cout << sizeof(C) << "\n";  // Result is not 3 as intuitively expected.
}

g++ ty.cpp
./a.out
1
1
1

В случае Java:

  • Нет простого способа узнать, сколько памяти занимает объект в Java; то есть нет sizeof оператор.
  • Размер объекта (пустой или непустой) зависит от платформы.

Размер экземпляра "пустого класса" (т.е. java.lang.Object) не равен нулю, поскольку экземпляр имеет неявное состояние, связанное с ним. Например, требуется состояние:

  • так что объект может функционировать как примитивный замок,
  • представлять свой хэш-код личности,
  • чтобы указать, был ли объект завершен,
  • ссылаться на класс времени выполнения объекта,
  • держать биты метки GC объекта,
  • и так далее.

Текущие JVM Hotspot используют хитрые трюки для представления состояния в заголовке объекта, который занимает два 32-битных слова. (Это расширяется в некоторых обстоятельствах; например, когда примитивная блокировка фактически используется, или после identityHashCode() называется.)

Поскольку каждый объект C++ должен иметь отдельный адрес, невозможно иметь класс с нулевым размером (кроме некоторых особых случаев, связанных с базовыми классами). В C++ есть больше информации : каков размер объекта пустого класса?,

Поскольку объект должен иметь адрес в памяти и иметь адрес в памяти, он должен занимать "некоторую" память. Так, обычно в C++ это наименьшее возможное количество, то есть 1 символ (но это может зависеть от компилятора). В Java я не был бы так уверен... у него могли бы быть некоторые данные по умолчанию (больше чем просто заполнитель как в C++), но было бы удивительно, если бы это было намного больше, чем в C++.

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

Я думаю, что Java, вероятно, делает то же самое. Причина, по которой C++ требует размер как минимум 1, заключается в том, что он требует, чтобы каждый объект был уникальным. Рассмотрим, например, массив объектов с нулевым размером. Все объекты будут находиться по одному адресу, поэтому у вас будет только один объект. Разрешение нуля звучит как рецепт проблем...

Он определяется стандартом C++ как "ненулевое значение", потому что выделенный объект должен иметь ненулевой размер, чтобы иметь отдельный адрес. Класс, который наследуется от пустого класса, однако, не обязан увеличиваться в размере, за исключением обычного увеличения виртуальной таблицы, если задействованы виртуальные функции.

Как уже отмечали другие, объекты C++ не могут иметь нулевой размер. Классы могут иметь нулевой размер только тогда, когда они действуют как подкласс другого класса. Посмотрите на ответ @Martin York для описания с примерами - а также посмотрите и проголосуйте за другие ответы, которые являются правильными в этом отношении.

В Java в виртуальной машине горячей точки накладные расходы памяти составляют 2 машинных слова (обычно 4 байта в 32 арках на слово) на объект для хранения информации бухгалтерского учета вместе с информацией о типе среды выполнения. Для массивов требуется третье слово для хранения размера. Другие реализации могут занимать другой объем памяти (классическая Java VM, по той же ссылке, занимала 3 слова на объект)

Я не знаю, есть ли оператор sizeof() в Java. Что вы можете сделать, это создать экземпляр пустого класса (иметь его сериализуемость), отправить его через PipedOutputStream и прочитать его как байтовый массив - byteArray.length даст вам размер.

В качестве альтернативы, запишите экземпляр в файл с помощью DataOutputStream, закройте файл, откройте его, и file.length() даст вам размер объекта. Надеюсь, это поможет, - MS

Другие вопросы по тегам