Topic: The realloc question: rationale?


Author: vandevod@cs.rpi.edu (David Vandevoorde)
Date: 1996/02/26
Raw View
>>>>> "KK" == Kerry Kimbrough <kk@onr.com> writes:
KK> Joe Buck wrote:
KK>>  You can, of course, call the C realloc().

KK> But then crash? My understanding is that mixture of alloc/free and
KK> friends with new/delete is not guaranteed to be valid and
KK> therefore is discouraged.  Not true?
[...]

Since you can provide your own new operators etc., you can ensure that
it's safe to use realloc with new/delete (or you can provide a function
based on realloc with similar functionality).

 Daveed

[ To submit articles: Try just posting with your newsreader.
        If that fails, use mailto:std-c++@ncar.ucar.edu
  FAQ:    http://reality.sgi.com/employees/austern_mti/std-c++/faq.html
  Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: James Kanze US/ESC 60/3/141 #40763 <kanze@lts.sel.alcatel.de>
Date: 1996/02/26
Raw View
In article <xsod973w4m5.fsf@glob.cs.rpi.edu> vandevod@cs.rpi.edu
(David Vandevoorde) writes:

|> >>>>> "KK" == Kerry Kimbrough <kk@onr.com> writes:
|> KK> Joe Buck wrote:
|> KK>>  You can, of course, call the C realloc().

|> KK> But then crash? My understanding is that mixture of alloc/free and
|> KK> friends with new/delete is not guaranteed to be valid and
|> KK> therefore is discouraged.  Not true?
|> [...]

|> Since you can provide your own new operators etc., you can ensure that
|> it's safe to use realloc with new/delete (or you can provide a function
|> based on realloc with similar functionality).

I don't think you can make it safe even providing your own operator
new/delete (or rather operator new[]/delete[], since realloc only
makes sense on arrays).  There are two problems:

1. It is, in fact, impossible to obtain the address actually returned
by operator new[].  The implementation is allowed to (and most do) ask
for extra memory in order to maintain the number of elements.
Typically, this memory will be in front of the first element, so the
compiler will `fix up' the address returned by operator new[] before
you ever see it.

2. The implementation is allowed to save this address in some sort of
cache.  For example, an alternate implementation of a new expression
for an array would be for the implementation to maintain an
associative array of addresses to counts.

--
James Kanze         Tel.: (+33) 88 14 49 00        email: kanze@gabi-soft.fr
GABI Software, Sarl., 8 rue des Francs-Bourgeois, F-67000 Strasbourg, France
Conseils,    tudes et r   alisations en logiciel orient    objet --
                -- A la recherche d'une activit    dans une region francophone
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: jbuck@Synopsys.COM (Joe Buck)
Date: 1996/02/26
Raw View
I wrote:
>> You can, of course, call the C realloc().

Kerry Kimbrough <kk@onr.com> writes:
>But then crash? My understanding is that mixture of alloc/free and friends
>with new/delete is not guaranteed to be valid and therefore is discouraged.
>Not true?

True.  If you want to use the C realloc, you'll need to mix it with malloc
and free.

>If true, then realloc'ing a new'ed object ain't kosher, and there goes the
>hope for specializing STL to implement realloc efficiently, i.e. w/o copy and
>delete.

That does not follow: my discussion of how to do the equivalent of realloc
using template specialization does not use the realloc function at all.
STL (at least in the HP implementation) does not use new directly to get
memory; allocators get raw memory, and placement new is used to turn raw
memory into objects.  STL already has to have a realloc mechanism: when
vectors and deques grow, they are reallocated and the older data is moved
to fit into the newly allocated space.  This is exactly what realloc does.
So answer #1 to those who cry out for realloc is to say "Use the STL
vector class: it looks like an array and does realloc for you".  For
arrays of T where T doesn't have a destructor, it's just the same.
To reallocate a vector to have capacity n, you just say

 myVector.reserve(n);

The HP implementation does the reallocation operation by calling
uninitialized_copy (using the copy constructor and placement new to
generate copies) followed by destroy (invoking the destructor on the
original objects).  This is inefficient for class objects that have lots
of sub-objects on the heap, as a shallow copy would be a lot less work.

My proposed modification is to replace the uninitialized_copy/destroy
combination with a "relocate" template that, by default, does the same
thing, but that can be specialized to move specific classes more
efficiently.  But all that does is make relocation work better; it's
already there now.





--
-- Joe Buck  <jbuck@synopsys.com> (not speaking for Synopsys, Inc)

Work for something because it is good,
not just because it stands a chance to succeed.    -- Vaclav Havel


[ To submit articles: Try just posting with your newsreader.
        If that fails, use mailto:std-c++@ncar.ucar.edu
  FAQ:    http://reality.sgi.com/employees/austern_mti/std-c++/faq.html
  Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: vandevod@cs.rpi.edu (David Vandevoorde)
Date: 1996/02/27
Raw View
>>>>> "JK" == James Kanze US/ESC 60/3/141 #40763
      <kanze@lts.sel.alcatel.de> writes:
JK> In article <xsod973w4m5.fsf@glob.cs.rpi.edu> vandevod@cs.rpi.edu
JK> (David Vandevoorde) writes:
[...]
JK> |> Since you can provide your own new operators etc., you can ensure that
JK> |> it's safe to use realloc with new/delete (or you can provide a function
JK> |> based on realloc with similar functionality).
[...]
JK> 1. It is, in fact, impossible to obtain the address actually returned
JK> by operator new[].  The implementation is allowed to (and most do) ask
JK> for extra memory in order to maintain the number of elements.
JK> Typically, this memory will be in front of the first element, so the
JK> compiler will `fix up' the address returned by operator new[] before
JK> you ever see it.

I was aware of that... which is why I didn't claim it was portable :^P
and suggested ``a function with similar functionality''.

JK> 2. The implementation is allowed to save this address in some sort of
JK> cache.  For example, an alternate implementation of a new expression
JK> for an array would be for the implementation to maintain an
JK> associative array of addresses to counts.

That's more troublesome ;-)

 Daveed
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: jbuck@Synopsys.COM (Joe Buck)
Date: 1996/02/23
Raw View
Kerry Kimbrough <kk@onr.com> writes:
>I gather from a recent message here that ANSI C++ (still) does not
>define the moral equivalent of realloc().

You can, of course, call the C realloc().

As I have proposed before in this group, a relocation "algorithm" could be
added to the STL, and used when vectors and deques are extended.  By
default, relocation would consist of a copy constructor call plus a
destructor call, but it could be specialized on a per-class basis
to something more efficient.

No extension to the language is needed, only to the STL.
--
-- Joe Buck  <jbuck@synopsys.com> (not speaking for Synopsys, Inc)

Work for something because it is good,
not just because it stands a chance to succeed.    -- Vaclav Havel
---
[ To submit articles: Try just posting with your newsreader.  If that fails,
                      use mailto:std-c++@ncar.ucar.edu
  FAQ:    http://reality.sgi.com/employees/austern_mti/std-c++/faq.html
  Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: kuehl@uzwil.informatik.uni-konstanz.de (Dietmar Kuehl)
Date: 1996/02/23
Raw View
Hi,

Kerry Kimbrough (kk@onr.com) wrote:
: I gather from a recent message here that ANSI C++ (still) does not
: define the moral equivalent of realloc(). This has always seemed
: regrettable to me. I also find the rationale expressed in the
: comp.lang.c++ FAQ to be completely unsatisfactory. Surely someone
: from this group can tell me why this omission is either a good thing
: or at least not a major obstacle for efficient implementation of
: extensible arrays.

I can't see why it is a good thing (neither can I see why it is a bad
thing...) but I can tell you why it is no major obstacle: It is
possible to

  - allocate "raw" (i.e. uninitialized memory) with 'operator
    new(size_t)' or relatives. Correspondingly, it is possible to
    release "raw" memory (i.e. memory where the objects contained were
    destructed) using 'operator delete(void*)' or relatives.
  - construct an object in-place using 'operator new(size_t, void*)'
    (placement new).
  - destruct a specific object of type 'T' using an explicit destructor
    call ('~T()').

These are the major ingredients necessary for a 'realloc()' function.
The only missing aspect is the possibility, to make use of the
knowledge of the memory system about the size of the memory block
occupied of the array to be resized. This is unfortunate but a
specialized array class can even circumvent this problem by using a
specialized memory management facility. I think an extension of the
language in this direction is neither necessary nor suitable (and maybe
even impossible for some environments).

The basic operation of a 'realloc()' function increasing the size of an
array would be to

  - allocate raw memory
  - copy the elements from the orginal array using placement new
  - construct the remaining objects
  - destruct the elements in the original array
  - release the the original array as raw memory
  - return a pointer to the newly allocated array

(An implementation without error checking of the procedure is not much
longer than this description. See e.g. the article "How to 'renew' a
built-in array" in comp.lang.c++.moderated or my implementation of an
array class at
<http://www.informatik.uni-konstanz.de/~kuehl/c++/array.h.html>).

Although this procedure CANNOT be used for arrays allocated with 'new
T[size]' (e.g. because the implementation can place auxiliary data in
front of the array such that the address to be passed to 'operator
delete[]()' cannot be figured out) it CAN be used inside an array class
where the built-in array used for the representation is created like
the returned array in the 'realloc()' function (of course it is also
impossible to release such an array with 'delete[]...': It is also
necessary to do this by hand).

Note, that this implementation even provides some additional freedom: A
built-in version of 'realloc()' can only use the copy constructor to
initialize the new array. A "home-grown" version can use a "move
constructor", i.e. a constructor which transfers allocated resources to
the new array leaving the original objects in a state only valid for
destruction (destruction is exactly what happens next to the orginal
objects).
--
dietmar.kuehl@uni-konstanz.de
http://www.informatik.uni-konstanz.de/~kuehl
I am a realistic optimist - that's why I appear to be slightly pessimistic
---
[ To submit articles: Try just posting with your newsreader.  If that fails,
                      use mailto:std-c++@ncar.ucar.edu
  FAQ:    http://reality.sgi.com/employees/austern_mti/std-c++/faq.html
  Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: Kerry Kimbrough <kk@onr.com>
Date: 1996/02/25
Raw View
Joe Buck wrote:
>
> You can, of course, call the C realloc().

But then crash? My understanding is that mixture of alloc/free and friends
with new/delete is not guaranteed to be valid and therefore is discouraged.
Not true?

If true, then realloc'ing a new'ed object ain't kosher, and there goes the
hope for specializing STL to implement realloc efficiently, i.e. w/o copy and
delete.

--

Regards,

Kerry Kimbrough

...................................................
Home: kk@onr.com           Work: kerry@cae-plus.com

[ To submit articles: Try just posting with your newsreader.
        If that fails, use mailto:std-c++@ncar.ucar.edu
  FAQ:    http://reality.sgi.com/employees/austern_mti/std-c++/faq.html
  Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: Kerry Kimbrough <kk@onr.com>
Date: 1996/02/20
Raw View
I gather from a recent message here that ANSI C++ (still) does not
define the moral equivalent of realloc(). This has always seemed
regrettable to me. I also find the rationale expressed in the
comp.lang.c++ FAQ to be completely unsatisfactory. Surely someone
from this group can tell me why this omission is either a good thing
or at least not a major obstacle for efficient implementation of
extensible arrays.

Regards,
Kerry Kimbrough
kk@onr.com
---
[ To submit articles: try just posting with your news-reader.
                      If that fails, use mailto:std-c++@ncar.ucar.edu
  FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html
  Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu.
]