Как я могу напечатать висячий указатель, в демонстрационных целях?
Я пытаюсь объяснить кому-то, почему у него есть висячий указатель и как на самом деле работает 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
неопределенной памяти производит неопределенную память.