Fetching the value of an invalid pointer is an implementation defined behavior in C++ according to this. Now consider the following C program:
printf("%p\n",(void*)p); // Is this undefined or implementation defined in behaviour C?
Expanding on Andrew Henle's answer:
From the C99 Standard, 6.2.4:
An object has a storage duration that determines its lifetime. There are three storage durations: static, automatic, and allocated. Allocated storage is described in 7.20.3. […] The value of a pointer becomes indeterminate when the object it points to (or just past) reaches the end of its lifetime.
Then in 184.108.40.206: the standard goes on describing
free(), mentioning that
freefunction causes the space pointed to by
ptrto be deallocated.
either an unspecified value or a trap representation
Certain object representations need not represent a value of the object type. If the stored value of an object has such a representation and is read by an lvalue expression that does not have character type, the behavior is undefined. […] Such a representation is called a trap representation.
Since the pointer becomes indeterminate, and an indeterminate value can be a trap representation, and you have a variable which is an lvalue, and reading an lvalue trap representation is undefined, therefore yes, the behavior may be undefined.