2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




Начать новую тему Ответить на тему
 
 С++ странный размер класса
Сообщение04.12.2012, 17:00 


11/06/12
20
Всегда считал, что размер экземпляра класса складывается из размеров полей этого класса, но при проверке результат оказался далеким от ожиданий: вызов sizeof для экземпляров различных классов показывал размер превышающий сумму размеров полей (порой в несколько раз). Вот простой пример:
Код:
class strangeSize{
public:
   int a, b;
   strangeSize() {};
   virtual ~strangeSize() {};
};
int main()
{
    cout << sizeof(strangeSize) << endl;
    return 0;
}

Данный код выводит 12.
Как рассчитывается реальный размер экземпляра и можно ли уменьшить его до размера суммы полей?

 Профиль  
                  
 
 Re: С++ странный размер класса
Сообщение04.12.2012, 17:22 
Заслуженный участник


04/05/09
4587
Во первых, объекты некоторых классов содержат поля, неявно добавленные компилятором. Наиболее распространённое такое поле - указатель на таблицу виртуальных методов. Как можно догадаться по названию, этот указатель есть у классов с виртуальными методами, как в вашем примере. Размер этого поля обычно равен размеру указателя, 4 байта в вашем примере. Есть ещё варианты, например указатель на виртуальную базу.
Во вторых, некоторые поля могут сдвигаться для выполнения требований по выравниванию для данного процессора. Например, класс с полями char, int, char, int будет иметь размер как у 4-х int.

 Профиль  
                  
 
 Re: С++ странный размер класса
Сообщение04.12.2012, 17:43 


11/06/12
20
Спасибо, venco.
О том, что указатель на таблицу хранится в экземпляре не знал.
P.S. Для регулирования выравнивания существует такая конструкция:
Код:
#pragma pack(push, 1)
class myClass
{
    // ...
};
#pragma pack(pop)

 Профиль  
                  
 
 Re: С++ странный размер класса
Сообщение04.12.2012, 17:50 
Заслуженный участник


04/05/09
4587
Mr Alexey в сообщении #654136 писал(а):
P.S. Для регулирования выравнивания существует такая конструкция:
Только использовать её надо осторожно, выравнивание не зря существует.

 Профиль  
                  
 
 Re: С++ странный размер класса
Сообщение04.12.2012, 18:15 
Заслуженный участник
Аватара пользователя


30/01/06
72407
Mr Alexey в сообщении #654136 писал(а):
P.S. Для регулирования выравнивания существует такая конструкция

не переносимая. Избегайте непереносимого кода.

 Профиль  
                  
 
 Re: С++ странный размер класса
Сообщение05.12.2012, 01:54 
Заслуженный участник


09/09/10
3729
Mr Alexey в сообщении #654136 писал(а):
О том, что указатель на таблицу хранится в экземпляре не знал.

А где ему храниться, интересно? Таблица виртуальных функций — это, в сущности, runtime-тип объекта, который просто необходимо знать для реализации полиморфизма.

Ну а так есть еще одна возможность: у объектов в debug сборках от майкрософтовского компилятора бывают отладочные поля (и поэтому debug и release сборки бинарно несовместимы... фанаты *nix хохочут и показывают языки, я так полагаю).

И да, не надо ручками лезть в выравнивание. Вы выиграете пять килобайт места, а проиграете тридцать процентов процессорных тактов — а если, не дай бог, ваш код попытаются запустить на ARM'е, он просто вылетит с misaligned access.

 Профиль  
                  
 
 Re: С++ странный размер класса
Сообщение05.12.2012, 06:59 
Заслуженный участник
Аватара пользователя


01/08/06
3131
Уфа

(В защиту ручного управления выравниванием)

У структур, входящих в интерфейсы модулей (не классов, конечно) бывает полезно фиксировать выравнивание, чтобы избежать проблем с "разъезжанием" структур внутри программы и во внешнем модуле (собираемом другим компилятором)

 Профиль  
                  
 
 Re: С++ странный размер класса
Сообщение05.12.2012, 15:25 
Заслуженный участник
Аватара пользователя


30/01/06
72407

(Оффтоп)

Joker_vD в сообщении #654387 писал(а):
а если, не дай бог, ваш код попытаются запустить на ARM'е, он просто вылетит с misaligned access.

Скорей, просто при компиляции на ARM выравнивание будет сделано по требованиям архитектуры, что бы там ни запросил программист. Проблема может возникнуть только при передаче данных между системами, скажем, в канале связи x86-ARM. Но форматирование данных для каналов связи - отдельная история, и если правильно его сделать, всё будет окей.

worm2 в сообщении #654408 писал(а):
внутри программы и во внешнем модуле (собираемом другим компилятором)

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

 Профиль  
                  
 
 Re: С++ странный размер класса
Сообщение05.12.2012, 18:09 
Заслуженный участник


09/09/10
3729

(Оффтоп)

Munin в сообщении #654525 писал(а):
Но форматирование данных для каналов связи - отдельная история

Ага, это очень заманчиво: просто сказать send(socket, (char*)&myStruct, sizeof myStruct, flags). Но увы, выравнивание, порядок байт в слове и т.п. разбивают такие мечты вдребезги. Поэтому лучше явно где-то выписать формат данных в канале, и уже приводить к нему/от него.

 Профиль  
                  
 
 Re: С++ странный размер класса
Сообщение05.12.2012, 23:03 
Заслуженный участник
Аватара пользователя


30/01/06
72407

(Оффтоп)

Ага, заманчиво, до первой набитой шишки. Потом наступает просветление и стадия google serialization.

 Профиль  
                  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 10 ] 

Модераторы: Karan, Toucan, PAV, maxal, Супермодераторы



Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group