В коде, опубликованном в вашем вопросе, вы указали компилятору действовать так, как будто адрес pi.denum
на самом деле является адресом fraction struct
.
Это не так, и поэтому высамостоятельно в получении правильной адресации памяти.C (или C ++) разместит вашу структуру в памяти в указанном вами порядке, с учетом только заполнения для выравнивания.
Итак, на машине с 32-разрядными целочисленными значениями и типичным 32-разрядным выравниванием для 32-в битах, ваша строка ((fraction*)&(pi.denum))->num=12;
установит pi.denum
в 12, а не pi.num
.->num
- это смещение от указателя (смещение равно нулю), а ваш указатель равен pi.denum
, поэтому устанавливается pi.denum
.
Это не приведет к сбою, потому что вы простоиспользовал своеобразное выражение для адресации памяти, которая правильно распределена в вашем стеке.
Следующий код ((fraction*)&pi.denum)->denum=33;
будет записывать в память вне выделения pi
.Сбой или просто перезапись другой переменной зависит от того, что еще вы распределили в стеке, и, возможно, от настроек компилятора и компилятора.
Если вы на самом деле хотите записать память, которая следует вашей структуре, а затем прочитать ееназад, то же самое адресное выражение сделает это за вас, например
int myTest = ((fraction*)&pi.denum)->denum;