#c #pointers #memory-address
#c #указатели #память-адрес
Вопрос:
Возможно ли в C получить содержимое адреса в памяти, если у меня нет указателя на него, но у меня есть сам адрес как a uint_32
?
Спасибо
Редактировать
Я пишу в эти местоположения и пытался проверить, правильно ли работает моя функция write(), поэтому я хотел вручную выполнить чтение с адресов. Упомянутое выше «содержимое» имеет тип uint64_t
, и это то, что я пытался сделать, но это дает мне Segmentation Fault
.
uint64_t *contents = reinterpret_cast<uint64_t*>(start_address);
cout<< hex << "Contents: " << *contents << endl;
Что я здесь делаю не так?
Комментарии:
1. Я думаю, вам нужно будет дать больше информации о том, в какой ситуации вы находитесь / чего вы пытаетесь достичь, чтобы получить полезные ответы.
Ответ №1:
Не уверен в переносимости, но вы можете использовать reinterpret_cast<>
. например
uint_32 adrs;
int *p = reinterpret_cast<int*>(adrs); // int* should be 32-bit for portable code
Комментарии:
1. Я попробовал ваше предложение (см. Раздел РЕДАКТИРОВАНИЕ в вопросе), но по какой-то причине я продолжаю получать ошибку сегментации. Почему это происходит?
2. @zohair, тогда есть вероятность, что данные указателя хранятся
uint_64
неправильно.
Ответ №2:
Да, но только если адрес находится в вашем адресном пространстве (или если вы работаете на микроконтроллере или в пространстве ядра). В противном случае это вызовет ошибку seg.
Просто приведите uint_32 к указателю int и разыменуйте его:
int contents = *((int*)uintAddress);
Комментарии:
1. Вы должны использовать reinterpret_cast<> вместо приведения в стиле C (отмечая тег C , а не тег C).
2. Каковы преимущества этого по сравнению с приведением в стиле C?
3. Приведения в стиле C могут отбрасывать константность, тогда как reinterpret_cast<> amp; static_cast<> не могут (не то чтобы это имело отношение к вашему ответу, но просто знайте, что приведение в стиле C более опасно, чем reinterpret_cast<> ).
4. @Chriszuma: В этом случае просто становится более ясно, что вы делаете что-то странное. В более общем плане приведения C позволяют ограничить возможные типы преобразований (например, сохранение
const
квалификаторов или предотвращение преобразований между несвязанными типами классов), что упрощает обнаружение ошибок.
Ответ №3:
Да, вы можете, если вы приведете это целое число к указателю:
SomeData value = *reinterpret_cast<SomeData*>(some_int);
Но вы должны быть на 100% уверены, что ваше целое число действительно является адресом, иначе могут произойти плохие вещи. Так что это считается плохой практикой и обычно является взломом.
Ответ №4:
Вы просто приводите его к указателю и разыменованию.
Ответ №5:
Вариант в стиле C:
uint_32 x = 0xc0de;
int *addr = (int*)x;
printf("Address %d contains %d", x, *addr);
Комментарии:
1. это, вероятно, вызовет некоторую ошибку сегментации в 32-разрядных архитектурах с защищенным режимом, «отрицательные адреса» которых зарезервированы ядром.
2. Абсолютно. Кстати, «отрицательные адреса» IMO — неправильное определение.