Получение содержимого адреса в C

#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 — неправильное определение.