Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Выравнивание в структурах, откуда беруться лишние байты? 
:(
    Опции темы
bel_nikita
Дата 12.10.2003, 17:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Эксперт
Сообщений: 2304
Регистрация: 12.10.2003
Где: Поезд №21/22 ( ст . Прага )

Репутация: 21
Всего: 47



Есть структуры:
struct DspErrorParametr{
unsigned short UniqueNumber;
unsigned short Command; unsigned short ErrorNumber; unsigned short ParameterOrder;
unsigned short ParameterError;
};

размер этой структуры sizeof(DspErrorParametr)=10;

struct DspErrorParametr{
unsigned short UniqueNumber;
unsigned short Command; unsigned short ErrorNumber; unsigned short ParameterOrder;
unsigned short ParameterError;
union{
unsigned short wErrorValue;
} ErrorValue;
};

размер этой структуры sizeof(DspErrorParametr)=12;

struct DspErrorParametr{
unsigned short UniqueNumber;
unsigned short Command; unsigned short ErrorNumber; unsigned short ParameterOrder;
unsigned short ParameterError;
union{
unsigned short wErrorValue;
unsigned long dwErrorValue;
} ErrorValue;
};

размер этой структуры sizeof(DspErrorParametr)=16 вместо 14 !!!!!!!!!!!!!
sizeof(unsigned long)=4!
Не могу понять откуда берутся еще 2 байта?
Перестановка в union не помогает.



--------------------
user posted image — регистрация доменов от 150 руб.
PM MAIL WWW ICQ   Вверх
automax
Дата 12.10.2003, 22:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 54
Регистрация: 30.9.2002

Репутация: нет
Всего: нет



Есть подозрение на выравнивание по 4-х байтной границе.
PM MAIL   Вверх
RAN
Дата 13.10.2003, 08:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Экс. модератор
Сообщений: 709
Регистрация: 14.3.2003
Где: Щёлково Моск.обл.

Репутация: 5
Всего: 6



Я тоже занимался этими вопросами. В компиляторах есть опции для изменения выравнивания в структурах.
Если хочешь разобраться, что куда поместилось, то сделай break в проге и вычисляй значения

struct DspErrorParametr a;
(unsigned)&a.Command - (unsigned)&a и т.д.

Я такое с классами проделывал. Очень полезно. Лучше понимаешь как надо данные в классе размещать. Уже не будешь писать:
class A {
char ch1;
int i1;
char ch2;
long l1;
char ch3;
};
PM MAIL ICQ   Вверх
RAN
Дата 13.10.2003, 08:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Экс. модератор
Сообщений: 709
Регистрация: 14.3.2003
Где: Щёлково Моск.обл.

Репутация: 5
Всего: 6



Цитата
struct DspErrorParametr{
unsigned short UniqueNumber;
unsigned short Command; unsigned short ErrorNumber; unsigned short ParameterOrder;
unsigned short ParameterError;
union{
unsigned short wErrorValue;
unsigned long dwErrorValue;
} ErrorValue;
};

размер этой структуры sizeof(DspErrorParametr)=16 вместо 14 !!!!!!!!!!!!!


long выравнивается по 4 байтам от начала структуры, чтоб быстрее работало. А так как ты сделал union, то и short тоже. У тебя после ParameterError 2 байта не будут использоваться.
PM MAIL ICQ   Вверх
RAN
Дата 13.10.2003, 08:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Экс. модератор
Сообщений: 709
Регистрация: 14.3.2003
Где: Щёлково Моск.обл.

Репутация: 5
Всего: 6



Кстати, попробуй использовать double. Получишь выравнивание по 8 байтам.
PM MAIL ICQ   Вверх
bel_nikita
Дата 13.10.2003, 16:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Эксперт
Сообщений: 2304
Регистрация: 12.10.2003
Где: Поезд №21/22 ( ст . Прага )

Репутация: 21
Всего: 47



Спасибо!
До меня дошло.


--------------------
user posted image — регистрация доменов от 150 руб.
PM MAIL WWW ICQ   Вверх
DENNN
Дата 16.10.2003, 14:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 3878
Регистрация: 27.3.2002
Где: Москва

Репутация: 1
Всего: 43



см в MSDN #pragma pack
PM ICQ   Вверх
knave
Дата 21.10.2003, 14:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 320
Регистрация: 6.3.2003
Где: Санкт-Питербург ( Россия)

Репутация: 1
Всего: 5



#pragma pack (1) // выравнивание по одному байту
#pragma pack (2) // выравнивание по 2-м байту
#pragma pack (4) // выравнивание по 4-м байту


--------------------
С наилучшими пожеланиями !!!
PM MAIL ICQ   Вверх
bel_nikita
Дата 24.10.2003, 10:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Эксперт
Сообщений: 2304
Регистрация: 12.10.2003
Где: Поезд №21/22 ( ст . Прага )

Репутация: 21
Всего: 47



Не помогает sad.gif
Или я не так делаю

#pragma pack (push, 4)
.....
....
#pragma pack (pop)



--------------------
user posted image — регистрация доменов от 150 руб.
PM MAIL WWW ICQ   Вверх
knave
Дата 24.10.2003, 12:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 320
Регистрация: 6.3.2003
Где: Санкт-Питербург ( Россия)

Репутация: 1
Всего: 5



Конечно ты нетак делаеш, я же написал
#pragma pack (1) // выравнивание по одному байту

Пропиши это вначале cpp например или в каком нить h


--------------------
С наилучшими пожеланиями !!!
PM MAIL ICQ   Вверх
bel_nikita
Дата 24.10.2003, 13:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Эксперт
Сообщений: 2304
Регистрация: 12.10.2003
Где: Поезд №21/22 ( ст . Прага )

Репутация: 21
Всего: 47



так много warning'ов
у меня структура в *.Н. Этот хидер много где включается.
надо чтоб, только одну структуру выровнял.


--------------------
user posted image — регистрация доменов от 150 руб.
PM MAIL WWW ICQ   Вверх
bel_nikita
Дата 24.10.2003, 13:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Эксперт
Сообщений: 2304
Регистрация: 12.10.2003
Где: Поезд №21/22 ( ст . Прага )

Репутация: 21
Всего: 47



после #pragma pack (1)
у меня прога вообще не работает


--------------------
user posted image — регистрация доменов от 150 руб.
PM MAIL WWW ICQ   Вверх
bel_nikita
Дата 24.10.2003, 23:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Эксперт
Сообщений: 2304
Регистрация: 12.10.2003
Где: Поезд №21/22 ( ст . Прага )

Репутация: 21
Всего: 47



Спасибо всем за советы.
Вот дошли наконец руки, разобрался.
А теперь кому интересно, или у кого возникают проблемы с выравниванием
(а если не возникают, то с временами возникнутsmile.gif), поясню.
Типа дополню MSDN smile.gif
Вообще-то выравнивание, коварная штука.
Вот пример:

первая структура:
typedef struct _Struct1{
unsigned long ulPar1; // DWORD
unsigned short ushPar2; // WORD
unsigned short ushPar3; // WORD
} Struct1;
sizeof(Struct1)=8. Все отлично!

вторая структура:
typedef struct _Struct2{
unsigned long ulPar1; // DWORD
unsigned short ushPar2; // WORD
} Struct2;
sizeof(Struct2)=8, вместо 6! (Кто знает в чем фокус - может дальше не читатьsmile.gif)
Где справедливость?smile.gif
А справедливость надо поискать в #pragma pack(n). #pragma pack(n) - задает границы упаковки элементов,
где n - граница выравнивания.
#pragma pack(n) - действует только на Declaration.
Возможные границы выравнивания: 1, 2, 4, 8, 16.
По дефолту выравнивание идет по 8-ми байтной границе(VC++).
Но лучше применять следующую конструкцию:
....
#pragma pack(push, _identifier, n)// Входим в блок выравнивания по n-байтной границе
...
// То что требуется выровнять - равняем
...
#pragma pack(pop, _identifier)// Выходим из блока
....

Не-еее, закалебаюсь писать, лучше пример кода приведу, будет понятнее и нагляднее.

typedef struct _Struct1 {
/*000*/ unsigned short Par1;
/*002*/ unsigned short Par2;
/*004*/ union{
unsigned long Par3;
unsigned short Par4;
/*008*/ } Union;
} Struct1; // sizeof(Struct1)=8; OK

typedef struct _Struct2 {
/*000*/ unsigned short Par1;
/*002*/ unsigned short Par2;
/*004*/ unsigned short Par3; // Выравнивание вставляет компилер!!!
/*006*/ // А здесьсь прячутся 2 байта mad.gif
/*008*/ union{
unsigned long Par4;
unsigned short Par5;
/*012*/ } Union;
} Struct2; // sizeof(Struct2)=12; ERROR!

#pragma pack(push, _start, 2) // Начинаем выравнивание по двубайтной границе
typedef struct _Struct {
/*000*/ unsigned short Par1;
/*002*/ unsigned short Par2;
/*004*/ unsigned short Par3; // Нет проблем thumbs-up.gif
/*006*/ union{
unsigned long Par4;
unsigned short Par5;
/*010*/ } Union;
} Struct; // sizeof(Struct2)=10; То что надо!
#pragma pack(pop, _start) // Заканчиваем выравнивание и компилятор дальше выравнивает по Default'у

Надеюсь моя писанина кому-нить будет полезна. Ведь я писал это не от того что я такой вумный, а для того, что это может пригодится, и не мучаться от того, что данные из буфера забираются/кладутся не так, как хотелость бы.
Во, как получается, сам задал вопрос на форуме и сам дал на него ответsmile.gif


--------------------
user posted image — регистрация доменов от 150 руб.
PM MAIL WWW ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0544 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.