mrjbom
@mrjbom

В какого типа переменных хранить адреса?

Пишу утилиту работающую с памятью и адресами, но не могу решить в каком типе переменных хранить адреса.
То есть, есть некая функция SOME_TYPE find_free_mem(size_t size); её задача просто найти адрес и выдать его, сам я в коде не собираюсь этим адресом пользоваться.
Получается, вместо SOME_TYPE использовать какой-то указатель я не хочу, т.к. боюсь по нему случайно обратиться, а просто uint32_t не подходит, т.к. боюсь спутать с каким-то числом.
Я думаю просто определить какой-то typedef addr_t uint32_t, хорошее ли это решение? Есть ли в си готовые готовые typedef'ы для такого дела?
  • Вопрос задан
  • 182 просмотра
Решения вопроса 1
@MarkusD Куратор тега C++
все время мелю чепуху :)
Для подобных целей уже давно заведены intptr_t и uintptr_t [?], а еще ptrdiff_t [?].
Именно эти типы и стоит использовать для прямой работы с адресами.

Теги C и C++ смешивать не совсем уместно. Это мешает выбору более подходящего варианта ответа.
В C++, например, если нужно только хранить адрес и позволять с ним только определенные операции, лучше мог бы подойти enum class MemoryAddress : uintptr_t;. Пустое перечисление с достаточной шириной и выравниванием избавит от возможности случайно что-то куда-то прибавить или умножить, да и от неявных преобразований убережет. А перегрузка операторов поможет разрешить только определенные операции.
Но в C так не получится.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 3
@dima20155
you don't choose c++. It chooses you
Что значит боитесь случайно обратиться к указателю?
Сделайте указатель констатнтным, где это нужно,чтобы вы могли лишь посмотреть значение по указателю, но не могли изменить значение по указателю
Напишите класс-обертку, которая не возволит случайно изменить значение по указателю (переопределить operator* -> и так далее)

Возвращаясь к вашему вопросу: храните в любой переменной, которая может адресовать всю нужную вам память, но имейте в виду, что в век 64битных процессоров указатель должен иметь тип uint64_t большинстве современных платформ, иначе вы потеряете возможность адресовать большую часть памяти (если, конечно, ваша целевая платформа не MCU или что-то в этом роде)
Ответ написан
Комментировать
В C используетсяvoid *, обратиться по нему без преобразования типа не получится
Ответ написан
Комментировать
@Mercury13
Программист на «си с крестами» и не только
Вариантов много.
1. Непрозрачные указатели, которые нельзя разыменовывать.
struct OpaqueAddress;
using Address = OpaqueAddress*;

2. void*, const void*.
3. uintptr_t.
4. Жёсткие int’ы, если работаем с конкретной посторонней прогой под конкретную архитектуру (например, пишем чит к игре).
using Address = uint32_t;
5. Enum class, основанный на соответствующем int’е.
enum class Address : uintptr_t { NUL = 0 };
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы