Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Занимает пмаяти прога больше чем надо


Автор: gepard 14.6.2004, 07:48
Код

#include <stdio.h>
struct cls
{
float  f1;
float  f2;
float  f3;
float  f4;
float  f5;
int  i1;
int  i2;
int  i3;
bool  b1;
bool  b2;
double  d1;
};
void main()
{
printf("%d\n", sizeof(cls));
printf("%d\n", sizeof(int)*3+sizeof(float)*5+sizeof(double)+sizeof(bool)*2);
}

Появится две строчки:
Цитата

48
42

Как так? Куда память утекает?

Автор: chipset 14.6.2004, 08:00
а сама структура разве не учитывается? withstupid.gif

Автор: bel_nikita 14.6.2004, 08:32
gepard
Дык, а про выравнивание забыл? smile.gif
Цитата
#pragma pack(push, _Struct, 1) // выставляем границу выравнивания в 1 байт
struct cls
{
float  f1;
float  f2;
float  f3;
float  f4;
float  f5;
int i1;
int i2;
int  i3;
bool  b1;
bool  b2;
double  d1;
};
#pragma pack(pop, _Struct) // выравнивание по дефолту

Вот теперь проверь thumbs-up.gif

Автор: gepard 14.6.2004, 09:57
chipset
Цитата
а сама структура разве не учитывается?

1 b, но никак не 6.
bel_nikita
Блин, вот что значит кодить в 1 ночи wow.gif
До этого сидел листал посты с форума и видел тему про выравнивание. Почитал же ещё!
Всё, пора завязывать bored.gif
Кстати, а что творит это выравнивание?
Как определить, когда его надо использовать(кроме проверки на размер структуры, конечно )

Автор: bel_nikita 14.6.2004, 10:47
gepard
Цитата
Как определить, когда его надо использовать(кроме проверки на размер структуры, конечно )

Очень просто. Стандартно граница выравнивания стоит в 8 байт. Вообще-то это доку к компилеру смотреть надо. Там такие вещи обязательно пишут.
Так, вот, если ты используешь структуры или классы в которых есть типы меньше 8 байт, то надо выравнивать. Хотя не обязательно. Это смотря для чего используется структура. Например, если ты некий класс или структуру проецируешь на память. Ну или, например чтение с файла. Ты знаешь, что данные в файле записаны в виде cls . Тебе надо их считать. Так вот, если у тебя выравнивание в 8 байт, то будут траблы tounge.gif

Рано или поздно у всех такие проблемы возникают. И довольно часто задаются вопросы по этому поводу. Только вот в FAQ этого почему-то нет sad.gif

Вот, два примера. Посмотри как память распределяется. Думаю все ясно станет
Код
//#pragma pack(push, _Struct, 1)
struct cls
{
unsigned   f1;
unsigned  f2;
unsigned char  f3;
unsigned char  f4;
unsigned  f5;
};
//#pragma pack(pop, _Struct)

/*
         unsigned  unsigned  unsigned  unsigned  unsigned
                              char     char
            f1        f2       f3        f4         f5
 bytes: [1|2|3|4] [5|6|7|8]  [9|10]   [11|12] [13|14|15|16]

 sizeof()=16

*/

Код
#pragma pack(push, _Struct, 1)
struct cls
{
unsigned   f1;
unsigned  f2;
unsigned char  f3;
unsigned char  f4;
unsigned  f5;
};
#pragma pack(pop, _Struct)


/*
         unsigned  unsigned  unsigned  unsigned  unsigned
                              char     char
            f1        f2       f3        f4         f5
 bytes: [1|2|3|4] [5|6|7|8]   [9]       [10]   [11|12|13|14]

 sizeof()=14

*/

Наверное еще будет вопрос: А почему имеено выравнивание по границе 8 байт, а не 1. Ответ прост - оптимизация smile.gif

Автор: gepard 14.6.2004, 10:52
Цитата
Рано или поздно у всех такие проблемы возникают. И довольно часто задаются вопросы по этому поводу. Только вот в FAQ этого почему-то нет

По-моему стоило бы поместить в FAQ.
bel_nikita
Спасибо, за объяснение.

Автор: lynx_916 14.6.2004, 11:20
не КБ а Б
размер-то в байтах!

Автор: gepard 14.6.2004, 15:33
Цитата
не КБ а Б
размер-то в байтах!

Без флейма.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)