Ben Bacarisse
4/21/2011 1:43:00 PM
cri@tiac.net (Richard Harter) writes:
> On Wed, 20 Apr 2011 21:22:38 +0200, Steve Keller <keller@no.invalid>
> wrote:
<snip>
>>To avoid numerous calls to realloc() I have often written code like
>>this:
>>
>> struct foo *p, *new, *a = NULL;
>> int count = 0, alloced = 0;
>> while (p = get_item()) {
>> if (count >= alloced) {
>> new = realloc(a, (alloced += 256) * sizeof(*a));
>> if (!new)
>> break;
>> a = new;
>> }
>> a[count++] = *p;
>> }
>>
>>But should one really do this or should one rely on the standard
>>library to handle things in an intelligent way, even without knowing
>>how many and how large the items will be?
>
> When you don't know how large an array might grow, the usual practice
> is to increase the size by some multiplicative factor. I usually use
> a factor of 1.5 but 2 is probably the most common choice. Thus
>
> new = realloc(a, (alloced *=2) * sizeof(*a)); /* Factor of 2 */
> new = realloc(a, (alloced += alloced/2) * sizeof(*a)); /* 1.5 */
Small point to watch out for: multiplicative schemes don't work when
alloced is zero to start with (as in this example). There are lots of
fixes, of course. I often just add a constant:
new = realloc(a, (alloced += alloced/2 + 8) * sizeof(*a));
which gives a minimum starting size. Alternatively you can special-case
the first allocation or start with alloced not zero (which can affect the
logic of the loop since it is, effectively, a lie).
<snip>
--
Ben.