Подтвердить что ты не робот

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

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

4b9b3361

Ответ 1

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

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

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

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

Заметка:

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

Пример:

#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

Ответ 2

В случае Java:

  • Нет простого способа узнать, сколько памяти занимает объект в Java; т.е. нет оператора sizeof.
  • Есть несколько способов (например, использование Instrumentation или сторонних библиотек), которые дадут вам число, но смысл имеет нюанс 1; см. в Java, как лучше определить размер объекта?
  • Размер объекта (пустой или непустой) зависит от платформы.

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

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

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


1 - Например, включает ли размер строкового объекта, созданного new String("hello") размер этого резервного массива, который содержит символы?С точки зрения JVM этот массив является отдельным объектом!

Ответ 3

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

Ответ 4

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

Ответ 5

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

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

Ответ 6

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

Ответ 7

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

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

Ответ 8

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

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