Other languages on non-unix platforms resort to what are called descriptors, usually kept in a global array. Old VMS did something like that in the kernel, for example. User processes had string descriptors in user space as well. The BSTR in Windows is a string descriptor and is derived from the VMS model -
/* this is the general idea */
void *ptr; /* copy of the base address */
size_t len; /* bytes allocated */
The descriptor table(s) require maintenance for every single malloc, free, and realloc call you make. So it's best to write a wrapper for each call that does the maintenance. It's pretty good for preventing overruns.