Легенда:
новое сообщение
закрытая нитка
новое сообщение
в закрытой нитке
старое сообщение
|
- Напоминаю, что масса вопросов по функционированию форума снимается после прочтения его описания.
- Новичкам также крайне полезно ознакомиться с данным документом.
Спасибо за реакцию. 19.11.05 09:55 Число просмотров: 1732
Автор: void <Grebnev Valery> Статус: Elderman
|
Спасибо за реакцию.
> В Ричи и Кернигане точно есть. У Страустрапа тоже должно > быть, порыться надо, но смысл?...
Мне интересен стандарт, а не придумщики этих языков. Часто, то, что мы используем, и то, что норма для партикулар компилер - вовсе не стандарт.
Например, void main (void) - норма для Borland & Microsoft. Но это нарушение стандарта.
> Подводные камни не в этом! > Явный акцент делается на массив структур. Упоминается, что > компилятор для оптимизации работ строк кэша может размещать > элементы массива структур с адреса кратного степени двойки, > а размер структуры может быть больше, > чем сумма размера ее элементов.
<skip>
Как раз подводные камни не в этом. Если ты используешь sizeof(), то это тебя гарантирует, что размер всегда будет определён верный. Проблема (вернее типовая ошибка) в том, если девелопер иcпользует:
1) #define MYSRTUCTSIZE ... вместо sizeof() хоть для структур, хоть для их массивов влюбыхоперациях с памятью.
2) когда пытается адресовать поля внутри структуры используя указатель на структуру и некий офсет, определённый в соответствии с той картой распределения памяти, которая кажется программеру действительной (т.е. когда девелопер делает сильные предположения о карте памяти структуры):
struct a {
byte v1;
WORD v2;
};
a inst1;
a* pt = & inst1;
byte * pt2 = (byte*) pt;
// сомнительное присваивание v2 = 1
* ( ++pt2 ) = 1;
Пример выше почтиникогдане будет правильно работать на современных системах (мы никогда таким образом не изменим inst1.v2, кроме, как хакнем сами себя;)) ),
если только не поставить силой:
#pragma pack(1)
> Например для связки AMD/GCC структура, состоящая из трех > однобайтовых элементов может быть расширена до > четырехбайтового размера.
1) практическивсегдабудет расширена. выравнивание по границе байта очень редко используется; и, думаю, никогда по умолчанию.
2)
struct __declspec(align(32)) a
{
byte val3;
WORD val4;
};
sizeof вообще вернёт 32 байта ;)
> инициализировать при помощи memset() нужно будет надлежащим > образом, учитывая эти особенности. > А, вот, к стати по поводу распределения адресного > пространства говорится, что оно должно распределяться по > порядку (насколько я помню).
Нет, чуть-чуть не так... гарантируется только выделение сплошного (непрерывного) куска памяти.
карта памятине_гарантируется Порядок в смыле очерёдности будет, но про расположение отдельных полей - см.выше (нет гарантии). Максимум, что ты можешь сделать - изменять align для всего проекта, модуля или отдельной структуры.
> "дырки"? То есть
Конечно есть.
> Размер структуры должен учитывать все "дырки" для > правильного динамического выделения памяти для масива > структур.
Ты не прав здесь немного, имхо. Опреции с памятью всегда будут коректными, если используешь sizeof.
sizeof всегда вернёт тебе правильное значение размера структуры, независимо от выравнивания структуры по границе байта, слова и т.д. Важно здесь другое - не делать сильных предположений о размере структуры (типа #define STRUCTURE_SIZE .... ) при распределении памяти, или навигации внутри массивов.
ПС. В контексте топика. amirul прав, на мой взгляд. "дыры" всегда будут покрыты 0 memset-ом, если использовать sizeof для всей структуры.
|
|
|