| 
  | 
Message-ID: <4gaupsoevltr3ollhvpufiixh6q63yygjkuvfpn35coibu4bex@gq7imsz7c2uf>
Date: Fri, 31 Oct 2025 23:09:46 +0100
From: Alejandro Colomar <alx@...nel.org>
To: Thiago Macieira <thiago@...ieira.org>
Cc: Paul Eggert <eggert@...ucla.edu>, libc-alpha@...rceware.org, 
	musl@...ts.openwall.com, "A. Wilcox" <AWilcox@...cox-tech.com>, 
	Lénárd Szolnoki <cpp@...ardszolnoki.com>, Collin Funk <collin.funk1@...il.com>, 
	Arthur O'Dwyer <arthur.j.odwyer@...il.com>, Jonathan Wakely <jwakely@...hat.com>, 
	"Paul E. McKenney" <paulmck@...nel.org>
Subject: Re: Re: realloci(): A realloc() variant that works in-place
Hi Thiago,
On Fri, Oct 31, 2025 at 02:06:10PM -0700, Thiago Macieira wrote:
> On Friday, 31 October 2025 13:13:42 Pacific Daylight Time Alejandro Colomar 
> wrote:
> > Consider that realloci() would be significantly cheaper than realloc(3),
> > so even if you have an extra function, it might be worth it if it
> > succeeds a non-negligible number of times.
> > 
> > From what Thiago says, it seems that it would be worth it for them.
> > I suspect it's because things like std::string often grow or shrink by
> > small amounts compared to the previous size, as operations on strings
> > don't change their length significantly quite often.
> 
> Note I'm not talking about growing/shrinking std::strings themselves, but 
> growing/shrinking arrays (std::vector) of std::strings. The libsdc++ 
> std::string is 32 bytes in size and is not relocatable via memcpy()able.
Thanks for clarifying.
> > So, while it would be one more call in user code, that call is very
> > cheap, and the code is really simple to use too:
> > 
> > 	if (realloci(p, size) == -1)
> > 		fall_back_to_expensive_path();
> 
> That's what my example on Godbolt did too.
> 
> > I wouldn't categorize it as hard to explain:
> > 
> > 		int realloci(void *p, size_t size);
> > 
> > 	realloci() changes the size of the memory block pointed to by
> > 	'p' to 'size' bytes.  This is done in-place, that is, without
> > 	changing its address.
> > 
> > 	The contents of the memory will be unchanged in the range from
> > 	the start of the region up to the minimum of the old and new
> > 	sizes.  If the new size is larger than the old size, the added
> > 	memory will not be initialized.
> 
> I'd add: if the new size is smaller than the old size, the bytes in that 
> storage are undefined, even if this function returned -1. That will allow an 
> implementation to MADV_DONTNEED the space, even if it can't officially change 
> the size of the allocation.
I'm not entirely sure.  What would be the new size?  Would it still be
the old one?  So, the higher contents are undefined but you're still
able to write to them?  It sounds weird.
I think if an allocator is unable to shrink, it likely is because it
really can't shrink, in which case I'd consider either accepting it and
not shrinking, or if I really want to shrink, call realloc(3) --or
malloc(3) and free-- as a fallback, accepting that I'd have to do the
work of reallocating.
> Would it be worth returning instead the new size, which may be bigger than the 
> requested size?
Hmmmm, while I wouldn't like the idea of realloc(3) or malloc(3) telling
the underlying size, I think I agree to realloci() telling the
underlying size.
The rationale is that if a programmer uses realloci(), they're
explicitly expressing interest in minimizing realloc(3) calls, because
for some reason moving the contents is expensive.  So, it would be nice
if realloci() would be generous, by giving more size than asked for, and
telling the user the actual size.
I'll revise the specification as:
    Synopsis
		ssize_t realloci(void *p, size_t size);
    Description
	realloci() changes the size of the memory block pointed to by
	'p' to at least 'size' bytes.  This is done in-place, that is,
	without changing its address.
	The contents of the memory will be unchanged in the range from
	the start of the region up to the minimum of the old and new
	sizes.  If the new size is larger than the old size, the added
	memory will not be initialized.
	This function may allocate more bytes than requested.
    Return value
	This function returns the new size of the memory block, which
	might be larger than the requested size (but not smaller).
	On error, -1 is returned, and errno is set to indicate the
	error.
    Errors
	ENOMEM
		Not enough contiguous memory.
Have a lovely night!
Alex
-- 
<https://www.alejandro-colomar.es>
Use port 80 (that is, <...:80/>).
Download attachment "signature.asc" of type "application/pgp-signature" (834 bytes)
Powered by blists - more mailing lists
Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.