(int *) (addr)
преобразует числовое значение addr
в указатель int *
. Если не предпринимаются особые меры, эта операция небезопасна, поскольку произвольное значение addr
может нарушать требования выравнивания для int
. В общем случае, если значение addr
не кратно размеру int
, это может привести к неправильному чтению, что в итоге может привести к сигналу SIGBUS
.
Звездочка, наконец, получает значение int
, расположенное по этому адресу (называемое разыменованием), и сохраняет его в read_value
. Именно в этот момент может произойти неправильное чтение, если адрес недостаточно выровнен. Разыменование может также вызвать ошибку сегментации, если адрес окажется ограниченным или защищенным.
Я бы фактически объявил, что addr
относится к типу uintptr_t
, а не int
, поскольку это обеспечивает большую безопасность между приведением к int *
. uintptr_t
должен соответствовать размеру и представлению указателя, в то время как тип int
семантически не связан с указателем.