Форум программистов, компьютерный форум CyberForum.ru

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 96, средняя оценка - 4.64
alexsvk
8 / 8 / 1
Регистрация: 15.07.2010
Сообщений: 255
#1

оператор sizeof - C++

28.04.2011, 23:53. Просмотров 11668. Ответов 12
Метки нет (Все метки)

Добрый вечер!
Был сделан тест. Есть класс
C++
1
2
3
4
5
6
class A
{
int a;
char b;
double c;
};
В программе:
C++
1
2
A a;
cout<<sizeof(a)<<"\n";
При использовании MSVS 6.0 на экране: 16. Стоит 32х-разрядная Win7, т.е. в ответ: 4+1+8 = 13 байт.
Ещё один момент. При комментировании int a и double c, ответ 1, что правильно, после декомме-я int a, ответ 8. Почему всё происходит именно так. Есть варианты объяснений, что называется, без дальнейших вопросов?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
28.04.2011, 23:53     оператор sizeof
Посмотрите здесь:

C++ Объясните sizeof()
sizeof массива C++
sizeof C++
Оператор sizeof C++
sizeof( char * ) & sizeof(char) C++
sizeof (double) C++
sizeof() C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Vladimir.
155 / 155 / 10
Регистрация: 24.11.2009
Сообщений: 375
28.04.2011, 23:58     оператор sizeof #2
байтовое выравнивание ??
silent_1991
Эксперт С++
4952 / 3028 / 149
Регистрация: 11.11.2009
Сообщений: 7,026
Завершенные тесты: 1
29.04.2011, 00:01     оператор sizeof #3
Тут проявляется выравнивание - данные выравниваются по границам слова (размера типа int). В первом случае переменная с будет располагаться в памяти не непосредственно за переменной b, а будет отодвинута от неё на (sizeof(int) - sizeof(b)) байт. Вот и получается - a - 4 байта, b - один байт, 3 пустых байта - выравнивание, c - 8 байт, сумма - 16.
В остальных случаях - аналогично.
Evg
Эксперт CАвтор FAQ
17297 / 5545 / 347
Регистрация: 30.03.2009
Сообщений: 15,093
Записей в блоге: 26
29.04.2011, 12:23     оператор sizeof #4
Сообщение было отмечено автором темы, экспертом или модератором как ответ
Цитата Сообщение от silent_1991 Посмотреть сообщение
Тут проявляется выравнивание - данные выравниваются по границам слова (размера типа int).
Не совсем так. У каждого типа помимо размера есть ещё и праметр выравнивание. Для базовых типов (кроме, обычно, long double) как правило выравнивание совпадает с размером. Т.е. переменная типа int (размером 4 байта) в памяти лежит по адресу, кратному 4 (т.е. говорят, что выровнена на 4). То же мамое касается и полей структуры. В структуре поле типа double должно быть выровнено на 8, а потому после переменных int и char (в сумме занимающих 5 байт) появится дырка, чтобы смещение поля double было 8.

Выравнивание всей структуры совпадает с максимальным выравниванием среди полей. Размер структуры должен быть кратен выравниванию структуры (в противном случае массив из структур будет лежать в памяти криво). Т.е. если структура содержит в себе "double + char", то в конце структуры всё равно образуется дырка в 7 байт из-за того, что размер стуркутуры должен быть кратен 8 (т.е. выравниванию структуры, которое есть выравнивание double)

Есть специальные конструкции, для принудительной установки выравнивания типов или переменных, но пока тебе это не нужно
alexsvk
8 / 8 / 1
Регистрация: 15.07.2010
Сообщений: 255
29.04.2011, 12:53  [ТС]     оператор sizeof #5
Цитата Сообщение от Evg Посмотреть сообщение
Не совсем так. У каждого типа помимо размера есть ещё и праметр выравнивание. Для базовых типов (кроме, обычно, long double) как правило выравнивание совпадает с размером. Т.е. переменная типа int (размером 4 байта) в памяти лежит по адресу, кратному 4 (т.е. говорят, что выровнена на 4). То же мамое касается и полей структуры. В структуре поле типа double должно быть выровнено на 8, а потому после переменных int и char (в сумме занимающих 5 байт) появится дырка, чтобы смещение поля double было 8.

Выравнивание всей структуры совпадает с максимальным выравниванием среди полей. Размер структуры должен быть кратен выравниванию структуры (в противном случае массив из структур будет лежать в памяти криво). Т.е. если структура содержит в себе "double + char", то в конце структуры всё равно образуется дырка в 7 байт из-за того, что размер стуркутуры должен быть кратен 8 (т.е. выравниванию структуры, которое есть выравнивание double)

Есть специальные конструкции, для принудительной установки выравнивания типов или переменных, но пока тебе это не нужно
Вы упомянули "для базовых типов", а что, если имеется long double. Что тогда?
Evg
Эксперт CАвтор FAQ
17297 / 5545 / 347
Регистрация: 30.03.2009
Сообщений: 15,093
Записей в блоге: 26
29.04.2011, 13:01     оператор sizeof #6
Сообщение было отмечено автором темы, экспертом или модератором как ответ
Цитата Сообщение от alexsvk Посмотреть сообщение
а что, если имеется long double. Что тогда?
У long double зачастию выравнивание 8, а размер 12 или 16. В том смысле что у long double размер не совпадает с выравниванием. Настройка выравнивания зависит от программных соглашений (ABI) на архитектуре. Но в средней своей массе принято так, что выравнивание базового типа совпадает с размером, кроме long double, потому что он слишком большой и выравнивают его, как правило, по разному
alexsvk
8 / 8 / 1
Регистрация: 15.07.2010
Сообщений: 255
29.04.2011, 13:42  [ТС]     оператор sizeof #7
Цитата Сообщение от Evg Посмотреть сообщение
У long double зачастию выравнивание 8, а размер 12 или 16. В том смысле что у long double размер не совпадает с выравниванием. Настройка выравнивания зависит от программных соглашений (ABI) на архитектуре. Но в средней своей массе принято так, что выравнивание базового типа совпадает с размером, кроме long double, потому что он слишком большой и выравнивают его, как правило, по разному
Сделал тест, оставив в классе лишь long double c. Размер оказался 8 байт.
Evg
Эксперт CАвтор FAQ
17297 / 5545 / 347
Регистрация: 30.03.2009
Сообщений: 15,093
Записей в блоге: 26
29.04.2011, 13:55     оператор sizeof #8
Цитата Сообщение от alexsvk Посмотреть сообщение
Сделал тест, оставив в классе лишь long double c. Размер оказался 8 байт.
Что за компилятор? Скорее всего он long double не поддерживает. Т.е. трактует его как double, что НЕ противоречит стандарту. На некоторых системах точно так же делают, потому что long double не такой уж и часто используемый тип, а его поддержка в аппаратуре - дело затратное (исходя из нечастой необходимости)

Добавлено через 3 минуты
А да, ты писал про MSVC 6.0. Там как раз такой случай: http://msdn.microsoft.com/en-us/library/aa246459.aspx
alexsvk
8 / 8 / 1
Регистрация: 15.07.2010
Сообщений: 255
29.04.2011, 13:56  [ТС]     оператор sizeof #9
Цитата Сообщение от Evg Посмотреть сообщение
Что за компилятор? Скорее всего он long double не поддерживает. Т.е. трактует его как double, что НЕ противоречит стандарту. На некоторых системах точно так же делают, потому что long double не такой уж и часто используемый тип, а его поддержка в аппаратуре - дело затратное (исходя из нечастой необходимости)
Спасибо за ответ
Действительно, исключение для 6.0
Evg
Эксперт CАвтор FAQ
17297 / 5545 / 347
Регистрация: 30.03.2009
Сообщений: 15,093
Записей в блоге: 26
29.04.2011, 14:05     оператор sizeof #10
Цитата Сообщение от alexsvk Посмотреть сообщение
Действительно, исключение для 6.0
Я бы не называл это исключение. MSVC-6.0 далеко не единственный компилятор, которы настроен что long double = double. И не только под intel'овскую архитектуру
Deviaphan
Делаю внезапно и красиво
Эксперт C++
1286 / 1220 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
29.04.2011, 15:27     оператор sizeof #11
На самом деле, всё немного сложнее. Например, вот два класса:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
class С1
{
    int i;
    double d;
    char c;
};
 
class С2
{
    double d;
    int i;
    char c;
};
Размер первого = 24 байта, второго = 16 байт. Т.е. важен ещё и порядок, в котором расположены поля, т.к. от этого сильно зависит выравнивание.
Evg
Эксперт CАвтор FAQ
17297 / 5545 / 347
Регистрация: 30.03.2009
Сообщений: 15,093
Записей в блоге: 26
29.04.2011, 15:34     оператор sizeof #12
Цитата Сообщение от Deviaphan Посмотреть сообщение
Т.е. важен ещё и порядок, в котором расположены поля
Это вытекает из того, что каждое поле должно быть выровнено на параметр выравнивания своего типа. А потому ничего тут дополнительно сложного нет
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
29.04.2011, 15:45     оператор sizeof
Еще ссылки по теме:

Sizeof C++
Немного о sizeof C++
C++ Fwrite (buffer , sizeof(char), sizeof(buffer), pFile)
C++ Sizeof(.) или constexpr size_t tmp = sizeof(.)
Sizeof структуры C++

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Deviaphan
Делаю внезапно и красиво
Эксперт C++
1286 / 1220 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
29.04.2011, 15:45     оператор sizeof #13
Цитата Сообщение от Evg Посмотреть сообщение
дополнительно сложного нет
Дополнительно сложно то, что размер структуры зависит от порядка полей. Но в принципе да, масло-масляное говорю.
Yandex
Объявления
29.04.2011, 15:45     оператор sizeof
Ответ Создать тему
Опции темы

Текущее время: 17:37. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru