Подтвердить что ты не робот

Эквивалент 0xDEADBEEF для 64-битной разработки?

Для разработки на С++ для 32-битных систем (будь то Linux, Mac OS или Windows, PowerPC или x86) У меня есть инициализированные указатели, которые в противном случае было бы undefined (например, они не могут сразу получите правильное значение) так:

int *pInt = reinterpret_cast<int *>(0xDEADBEEF);

(Чтобы сохранить ввод и DRY, правая часть будет обычно быть постоянным, например. BAD_PTR.)

Если pInt разыменовывается до того, как он получит правильное значение, тогда он немедленно сработает на большинстве систем (вместо сбой намного позже, когда какая-то память перезаписывается или собирается в очень длинный цикл).

Конечно, поведение зависит от аппаратное обеспечение (получение 4-байтового целого из нечетного адрес 0xDEADBEEF из пользовательского процесса может быть совершенно действителен), но сбой был на 100% надежным для всех системы, которые я разработал до сих пор (Mac OS 68xxx, Mac OS PowerPC, Linux Redhat Pentium, Windows GUI Pentium, Windows консоль Pentium). Например, на PowerPC это незаконно (шина ошибка), чтобы получить целое число из 4 байтов из нечетного адреса.

Что хорошего для этого в 64-битных системах?

4b9b3361

Ответ 1

Как правило, не имеет значения, какой именно шаблон вы пишете, важно определить шаблон, чтобы определить, где возникают проблемы. Так получилось, что в ядре Linux они часто выбираются так, что они могут быть захвачены, если адреса разыменованы.

Посмотрите в ядре Linux на include/linux/poison.h. Этот файл содержит различные значения яда для многих разных подсистем ядра. Нет соответствующей ценности яда.

Кроме того, вы можете проверить, что для каждой архитектуры включены файлы в исходном дереве ядра Linux для информации о том, что используется на определенных архитектурах.

Ответ 2

0xBADC0FFEE0DDF00D

Ответ 3

Согласно Wikipedia, BADC0FFEE0DDF00D используется для 64-разрядных систем IBM RS/6000 для обозначения неинициализированных регистров процессора.

Ответ 4

Большинство современных 64-битных систем позволяют использовать только младшие 2 48 – 2 52 биты адресного пространства; старшие биты адреса должны быть все-ноль. Некоторые чипы (например, amd64) также позволяют использовать самые высокие 2 48 – 2 52. Адреса вне этих диапазонов никогда не могут быть сопоставлены с доступной памятью; аппаратное обеспечение просто не позволит.

Поэтому я рекомендую вам использовать значение, близкое к 2 63 которое нигде не находится ни в одном из возможных пространств. Если ведущими четырьмя шестнадцатеричными цифрами являются 7ff8, значение будет представлять собой точку с плавающей запятой двойной точности, что удобно. Поэтому моя предложенная милая шестнадцатеричная фраза - 0x7FF8BADFBADFBADF.

Кстати, вы действительно не хотите использовать значение, близкое к 0, потому что это затрудняет определение смещения смещения NULL — доступ к члену структуры, например, — от разыменования ядовитого рисунка.

Ответ 5

Я предполагаю, что вы уже присвоили NULL (т.е. 0 без приведения типов). Это определенно самый безопасный выбор, так как теоретически допустимый указатель может указывать на адрес памяти 0xDEADBEEF (или любой другой адрес, не содержащий NULL).

Ответ 6

0xDEADBEEFBAADF00D может работать.

Ответ 8

Я думаю, что двух 0xDEADBEEF должно быть достаточно.

Ответ 9

Я вижу несколько ответов, утверждая, что NULL - хороший выбор, но я не согласен.

NULL часто используется как действительное возвращаемое значение из функций. Он указывает на возврат отказа или неизвестное значение. Это другое значение, чем "неинициализированный указатель".

Использование отладчика в коде и просмотр NULL затем оставят две возможности: указатель никогда не был инициализирован или ему не удалось выделить память.

Установка неинициализированного указателя на 0xDEADBEEF или 64-битный эквивалент означает, что указатель NULL указывает на намеренное значение.

Ответ 10

Конечно, это зависит от ОС и среды. Я не думаю, что 0xDEADBEEF обязательно является плохим указателем в произвольной 32-битной системе.

Реально, любая современная ОС должна защищать первые несколько страниц памяти процесса, поэтому NULL должен быть хорошим недопустимым значением указателя. Удобно, он уже заранее определен для вас.

Ответ 11

0x42 может работать как на 32-битной, так и на 64-битной? (Он все равно должен вызвать сбой, поскольку он достаточно близко к указателю NULL, и учитывая, что он довольно большой, скорее всего, вы не получили бы его в рамках регулярного разыменования поля структуры с указателем структуры, равным NULL).

Ответ 12

Поскольку система, над которой я работал, в основном работает на платформе x86_64, я использую следующее значение:

0xDEADBEEFDEADBEEF

Причины:

  • На платформе x86_64 в текущей реализации для адреса виртуальной памяти используются только младшие 48 битов, что означает, что любое значение> 2 ^ 48 должно работать: https://en.wikipedia.org/wiki/X86-64
  • Поскольку 0xDEADBEEF в 32-битной 0xDEADBEEF уже хорошо известен для этой цели, 0xDEADBEEFDEADBEEF в 64-битной версии просто более "обратно совместим"