I don't think e.g. C can safely do it either. e.g.
void something (void* p)
{
// trying to detect if p is a string, will typically scan for \0 and crash after only acccessing a few bytes.
}
// play with blocksize to get a block that might have unallocated memory behind it. I bet here a 64-bit page, 8192 bytes for relatively straight forward (embedded) mallocs.
#define blocksize 8192
{
byte* myp=malloc(blocksize);
myp[blocksize-2]='A';
myp[blocksize-1]='B';
something(&myp[blocksize-2]);
}
If you try to see if this is a string, eventually you will access beyond the allocation into unallocated memory, which only takes two bytes worth of iteration, and get a nice SIGSEGV/Access violation for your trouble.
And while this is artificial, such patterns exist in code e.g. when the routine e.g. handling of circular I/O buffers.
Debug info, checking if a pointer is in stack space or data space, accessing valid data memory is all implementation specific and not guaranteed by nearly any language.