Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I print a dangling pointer, for demonstration purposes?

I'm trying to explain to someone why they have a dangling pointer and how free actually works (and that pointers are values and thus are passed-by-value), but for that I think I need a way to print pointers that isn't "indeterminate" (as is the case with printf("%p", ptr)).

Would memcpy do the trick?

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]);
}
like image 621
SoniEx2 Avatar asked Jul 14 '18 23:07

SoniEx2


1 Answers

According to a strict reading of the C standards, you can't do anything with a dangling pointer: “indeterminate”, the state of memory that holds a dangling pointer, also describes the contents of uninitialized automatic variables, and these may have different values if you read them twice in a row(*).

The only way around the issue is to convert the pointer to uintptr_t while it is still valid. The result of the conversion is an integer and has the properties of integers:

#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);

(*) The C11 standard distinguishes automatic variables the address of which is not taken (“that could have been declared with the register storage class”), but Clang does not care.

To answer specifically your suggestion of using memcpy, note that memcpy of indeterminate memory produces indeterminate memory.

like image 66
Pascal Cuoq Avatar answered Sep 30 '22 12:09

Pascal Cuoq