Мы используем куки, чтобы пользоваться сайтом было удобно.
Хорошо
to the top
>
>
>
Отличие %p от %x

Отличие %p от %x

05 Апр 2013

В функциях семейства printf существуют спецификаторы типа "%p" и "%x".

  • x и X - вывод шестнадцатеричного числа. "x" использует маленькие буквы (abcdef), "X" большие буквы (ABCDEF).
  • p - вывод указателя. Вывод может различаться в зависимости от компилятора и платформы.

В 32-битных системах часто один спецификатор используют вместо другого, что на самом деле неверно. Рассмотрим пример:

int a = 10;
int *b = &a;
printf("%p\n",b);
printf("%X\n",b);

В Win32 системе на экране будет распечатано:

0018FF20
18FF20

Как видите результаты вывода с использованием "%p" и "%X" весьма схожи. Это схожесть и порождает неаккуратность в коде, что приводит к ошибкам при переносе программы на 64-битную платформу. Наиболее часто вместо "%p" используют "%X" для вывода значения указателя, что приводит к распечатке неверного значения, если объект расположен за пределами младших четырех гигабайт адресного пространства. Рассмотрим соответствующий пример 64-битной программы:

size_t Gb = 1024*1024*1024;
char *a = (char *)malloc(2 * Gb * sizeof(char));
char *b = (char *)malloc(2 * Gb * sizeof(char));
printf("use %%X: a=%X\n", a);
printf("use %%X: b=%X\n", b);
printf("use %%p: a=%p\n", a);
printf("use %%p: b=%p\n", b); 
use %X: a=80000040
use %X: b=40010040
use %p: a=0000000080000040
use %p: b=0000000140010040

Значение указателя "b" распечатано некорректно при использовании "%X".

Рассмотрим еще один пример. Хотя этот пример выглядит странно, код который приведен здесь в упрощенном виде, использовался в реальном приложении в подсистеме UNDO/REDO:

// Here the pointers were saved in the form of a string
int *p1, *p2;
....
char str[128];
sprintf(str, "%X %X", p1, p2);
// In another function this string was processed
// in this way:
void foo(char *str)
{
  int *p1, *p2;
  sscanf(str, "%X %X", &p1, &p2);
  // The result is incorrect values of pointers p1 and p2.
  ...
}

Результатом манипуляций указателями с использованием %X стало некорректное поведение программы на 64-битной системе. При этом обратите внимание, что подобные ошибки могут проявляться весьма редко. Для диагностирования этих и схожих дефектов рационально использовать анализатор PVS-Studio.

Библиографический список

Популярные статьи по теме


Комментарии (0)

Следующие комментарии next comments
close comment form
close form

Заполните форму в два простых шага ниже:

Ваши контактные данные:

Шаг 1
Поздравляем! У вас есть промокод!

Тип желаемой лицензии:

Шаг 2
Team license
Enterprise license
** Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности
close form
Запросите информацию о ценах
Новая лицензия
Продление лицензии
--Выберите валюту--
USD
EUR
RUB
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

close form
Бесплатная лицензия PVS‑Studio для специалистов Microsoft MVP
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

close form
Для получения лицензии для вашего открытого
проекта заполните, пожалуйста, эту форму
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

close form
Мне интересно попробовать плагин на:
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

close form
check circle
Ваше сообщение отправлено.

Мы ответим вам на


Если вы так и не получили ответ, пожалуйста, проверьте, отфильтровано ли письмо в одну из следующих стандартных папок:

  • Промоакции
  • Оповещения
  • Спам