Здесь много "грязного" беспорядка с адресами, сделанными здесь.Некоторые из этих вещей не рекомендуются или даже запрещены со стандартной точки зрения C.
Однако такие подстройки указателя / адреса обычно используются в низкоуровневом программировании (встроенные, встроенные программы и т. Д.), Когда некоторые детали реализации компилятораизвестны пользователю.Конечно, такой код не является переносимым.
В любом случае проблема здесь (после получения более подробной информации в разделе комментариев) заключается в том, что машина, на которой выполняется этот код, имеет 64-битную версию.Таким образом, указатели имеют ширину 64 бита, в то время как int
или unsigned int
имеют ширину 32 бита.
Таким образом, при сохранении адреса k
в p[0]
p[0] = k;
, в то время как p[0]
имеет тип unsigned int
, а k
имеет указатель типа на struct kai
, старшие 32 бита значения k
обрезаны.
Чтобы решить эту проблему, лучше всегоиспользуйте uintptr_t
, так как этот тип всегда будет иметь нужную ширину для хранения полного значения адреса.
uintptr_t *p = malloc(sizeof(uintptr_t));
Примечание : uintptr_t
необязательно, но обычно.Это достаточно для void*
, но, возможно, не указатель на функцию.Для совместимого кода правильное использование uintptr_t
включает указатель объекта -> void *
-> uintptr_t
-> void *
-> указатель объекта .