This motivation is very weak.
Not really, unless we are designing a new language from scratch (see
below).
I am quite sure that implementors of malloc routines implement the
simple optimization of avoiding the copy and returning the original
pointer if the new size is smaller that the size of the memory area
malloc used.
Sure, such as the example realloc implementation in the proposal:
http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1085.htm
Example:
p = malloc(30); /* Returns a pointer to a area */
/* from the 64 byte memory pool. */
. . .
p = realloc(p,40); /* As the new size is less than 64 */
/* no copy and same ptr is returned. */
vs.
p = malloc(30); /* Returns a pointer to a area */
/* from the 64 byte memory pool. */
. . .
if ( _msize(p) < 40 ) { /* _msize returns 64. */
p = realloc(p,40);
}
The cost of calling _msize can't be any different than the cost of
calling a realloc that doesn't need to do a copy.
What can be done with a _msize that isn't provided automatically with,
probably most (if not all), of todays malloc implementations?
Some clients do not want the expense of a copy and are willing settle
for less memory than the requested size in a realloc. Other clients can
not tolerate a copy, no matter what the expense. For example some
clients may have structs that are self-referencing:
struct MyType
{
struct MyType* head; // head and tail may point to this
struct MyType* tail;
};
....
MyType* p = realloc(p, newsize*sizeof(MyType));
Self-referencing structs can not be memcpy'd, and thus arrays of them
can not be realloc'd (at least not without post detection of address
change and fix up). And so it is beneficial to see if such arrays can
be expanded in place (the real thrust of the proposal).
The proposed sizeof_alloc(void*) is a minor player in this paper,
present mainly for transitional code. If you receive a malloc'd pointer
from a legacy server, you can find out the size of the allocated block
with sizeof_alloc. A non-legacy server would simply use request_malloc
instead of malloc, and thus receive the memory block and its allocated
size at the same time (if that information is useful). So in a newly
built system today, sizeof_alloc(void*) is somewhat redundant, and thus
would have weak motivation. But in today's context, where you might be
dealing with the transfer of memory ownership from legacy code, the
motivation for sizeof_alloc(void*) is significantly stronger.
But the above is really just a subtlety. To really answer your question
head on: Some clients can only expand their array in-place, and can not
use memcpy when placing the array into a larger block. Thus realloc is
inconvenient at best, and completely wrong at worst. To be able to
discover the true size of your allocated block of memory, and to also
discover if it can be expanded in-place, and by how much, can be very a
significant optimization.
A potential pitfall: clients must not (portably) assume that
sizeof_alloc(void*) is O(1) time complexity. While all malloc systems I
can think of can return this information, some of them may not do it in
constant time. Indeed, one of the malloc implementations I've written
for a very tight embedded system returns this information in O(log)
time. And so I advise clients that need this information to cache it,
instead of recomputing it on each need, unless it is known that the
underlying implementation can deliver in O(1) time.
-Howard