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

Я пытаюсь объяснить кому-то, почему у него есть висячий указатель и как на самом деле работает free (и что указатели являются значениями и, следовательно, передаются по значению), но для этого мне кажется, что мне нужен способ печати указателей, который не ' т "неопределенный" (как в случае с printf("%p", ptr)).

Будет ли Memcpy сделать трюк?

char buf1[sizeof(char *)];
char buf2[sizeof(char *)];
char *malloced = malloc(10);
memcpy(buf1, &malloced, sizeof(char *));
free(malloced);
memcpy(buf2, &malloced, sizeof(char *));
for (int i=0; i<sizeof(char *); i++) {
    printf("%hhd %hhd / ", buf1[i], buf2[i]);
}

1 ответ

В соответствии со строгим чтением стандартов C, вы ничего не можете сделать с висящим указателем: "неопределенное", состояние памяти, в котором находится висячий указатель, также описывает содержимое неинициализированных автоматических переменных, и они могут иметь разные значения если вы читаете их дважды подряд (*).

Единственный способ обойти эту проблему - преобразовать указатель в uintptr_t пока это еще действует. Результат преобразования является целым числом и имеет свойства целых чисел:

#include <stdint.h>
...
char *malloced = malloc(10);
uintptr_t ptr_copy = (uintptr_t) malloced;
...
free(malloced);
// it is valid to use ptr_copy here to display what the address was.
printf("The pointer was at: %" PRIxPTR "\n", ptr_copy);

(*) Стандарт C11 различает автоматические переменные, адрес которых не берется ("которые могли быть объявлены с помощью класса хранения регистров"), но Clang это не волнует.

Чтобы конкретно ответить на ваше предложение об использовании memcpy обратите внимание, что memcpy неопределенной памяти производит неопределенную память.

Другие вопросы по тегам