I know that it\'s a common convention to pass the length of dynamically allocated arrays to functions that manipulate them:
void initializeAndFree(int* anArr
To answer the question about delete[], early versions of C++ actually required that you call delete[n] and tell the runtime the size, so it didn't have to store it. Sadly, this behaviour was removed as "too confusing".
(See D&E for details.)
While it is possible to get the meta-data that the memory allocator places preceding the allocated block, this would only work if the pointer is truly a pointer to a dynamically allocated block. This would seriously affect the utility of function requiring that all passed arguments were pointers to such blocks rather than say a simple auto or static array.
The point is there is no portable way from inspection of the pointer to know what type of memory it points to. So while it is an interesting idea, it is not a particularly safe proposition.
A method that is safe and portable would be to reserve the first word of the allocation to hold the length. GCC (and perhaps some other compilers) supports a non-portable method of implementing this using a structure with a zero length array which simplifies the code somewhat compared to a portable solution:
typedef tSizedAlloc
{
size_t length ;
char* alloc[0] ; // Compiler specific extension!!!
} ;
// Allocating a sized block
tSizedAlloc* blk = malloc( sizeof(tSizedAlloc) + length ) ;
blk->length = length ;
// Accessing the size and data information of the block
size_t blk_length = blk->length ;
char* data = blk->alloc ;
You can't get it because the C committee did not require that in the standard.
If you are willing to write some non-portable code, you may have luck with:
*((size_t *)ptr - 1)
or maybe:
*((size_t *)ptr - 2)
But whether that works will depend on exactly where the implementation of malloc you are using stores that data.
It's up to the malloc
implementor how to store this data. Most often, the length is stored directly in front of the allocated memory (that is, if you want to allocate 7 bytes, 7+x bytes are allocated in reality where the x additional bytes are used to store the metadata). Sometimes, the metadata is both stored before and after the allocated memory to check for heap corruptions. But the implementor can as well choose to use an extra data structure to store the metadata.
After reading Klatchko's answer, I myself tried it and ptr[-1]
indeed stores the actual memory (usually more than the memory we asked for probably to save against segmentation fault).
{
char *a = malloc(1);
printf("%u\n", ((size_t *)a)[-1]); //prints 17
free(a);
exit(0);
}
Trying with different sizes, GCC allocates the memory as follows:
Initially memory allocated is 17 bytes.
The allocated memory is atleast 5 bytes more than requested size, if more is requested, it allocates 8 bytes more.
A non-standard way is to use _msize(). Using this function will make your code unportable. Also the documentation is not very clear on wheteher it will return the number passed into malloc()
or the real block size (might be greater).