Topic: [Q] mixing realloc and new


Author: wil@ittpub.nl (Wil Evers)
Date: 1995/07/06
Raw View
In article <LASSI.TUURA.95Jul5143640@jojo.cs.hut.fi> Lassi.Tuura@hut.fi
(Lassi A. Tuura) writes:

> Is there any portable method for a program to figure out whether
>  - an implementation uses extra space for the count?
>  - if so, where in the allocated memory this count is located
>    (or more interestingly, where the actual data is located)?
>  - whether the behaviour is equal for all classes and for other types?
>  - whether the behaviour varies at run time?

No, there isn't. The implementation is free to do as it pleases.
Obviously, for classes that have a non-trivial destructor, the count
passed to operator new[] must be stored *somewhere* because the
implementation must know how many objects to destruct when operator
delete[] is called.

> Actually, the most demanding question is the last two ones as the
> first two ones can be checked with scripts at configuration time. Does
> the standard require anywhere that the implementation should document
> the methods it uses and/or behave consistently?

No, it doesn't. Basically, it only says the system should work.

> I really wouldn't care if this information is implementation defined
> as long as it is defined, but at least there should be some way for a
> program(mer) figure things out. There are several reasons for these
> requirements.  Two of them are debugging memory allocators and garbage
> collection, neither of which can get any help from the compiler but
> which still need to implement their own memory allocation schemes
> _and_ memory walkers.

C++ allows you to replace the default memory allocation system in the
implementation by the one you like most. The replacement system could
define everything you ever wanted to know about it. (Of course, if some
class defines its own allocation scheme, then at least for that class
you're stuck with it.)

- Wil






Author: tony@online.tmx.com.au (Tony Cook)
Date: 1995/07/04
Raw View
Julian Pardoe LADS LDN X1428 (pardoej@lonnds.ml.com) wrote:
: I'd like to see the standard mandate that global new[] and delete[] must be
: compatible with malloc/free/realloc.

That wouldn't help much - as the pointer returned by calling the
function operator new[](size_t) is not necessarily the same as the
pointer returned by 'new T[count]' - the implementation may use some
memory for tracking the 'count'.

--
        Tony Cook - tony@online.tmx.com.au
                    100237.3425@compuserve.com





Author: Lassi.Tuura@hut.fi (Lassi A. Tuura)
Date: 1995/07/05
Raw View
> That wouldn't help much - as the pointer returned by calling the
> function operator new[](size_t) is not necessarily the same as the
> pointer returned by 'new T[count]' - the implementation may use some
> memory for tracking the 'count'.

Is there any portable method for a program to figure out whether
 - an implementation uses extra space for the count?
 - if so, where in the allocated memory this count is located
   (or more interestingly, where the actual data is located)?
 - whether the behaviour is equal for all classes and for other types?
 - whether the behaviour varies at run time?

Actually, the most demanding question is the last two ones as the
first two ones can be checked with scripts at configuration time. Does
the standard require anywhere that the implementation should document
the methods it uses and/or behave consistently?

I really wouldn't care if this information is implementation defined
as long as it is defined, but at least there should be some way for a
program(mer) figure things out. There are several reasons for these
requirements.  Two of them are debugging memory allocators and garbage
collection, neither of which can get any help from the compiler but
which still need to implement their own memory allocation schemes
_and_ memory walkers.

//LaT
--
Lassi A. Tuura                           Have you not known?
Lassi.Tuura@hut.fi                       Have you not heard?





Author: clamage@Eng.Sun.COM (Steve Clamage)
Date: 1995/07/05
Raw View
In article 95Jul5143640@jojo.cs.hut.fi, Lassi.Tuura@hut.fi (Lassi A. Tuura) writes:
>
>Is there any portable method for a program to figure out whether
> - an implementation uses extra space for the count?
> - if so, where in the allocated memory this count is located
>   (or more interestingly, where the actual data is located)?
> - whether the behaviour is equal for all classes and for other types?
> - whether the behaviour varies at run time?
>
>Actually, the most demanding question is the last two ones as the
>first two ones can be checked with scripts at configuration time. Does
>the standard require anywhere that the implementation should document
>the methods it uses and/or behave consistently?

No, to all your questions. In particular, consistent behavior is not
required, and inconsistent behavior is common. For example, some
implementations keep extra information for checking the validity only of
delete[], and only for types having a destructor. That is,
 char *pc;
 T* pT;  // T has a destructor
 delete pT; // unchecked (not an array)
 delete[] pc ; // unchecked (no destructor)
 delete[] pT; // checked

The implementation is allowed considerable freedom in implementing
new and delete. Some implementations supply a variety of allocators,
allowing you to pick one that best fits the needs of your application.

---
Steve Clamage, stephen.clamage@eng.sun.com







Author: jskim@rose.etri.re.kr (Kim Jungsun)
Date: 1995/07/01
Raw View
I have a question about which one to use to deallocate memory which we
obtained by calling strdup() --- free() or delete. In case of strdup(),
the user of strdup() have to deallocate a memory. But the problem is that
there is no way to find out whether strdup() used malloc() or new because
it is in the library.

I've briefly check the header files in gcc-2.7.0 and g++-2.7.0a. It seems
that the gcc makes use of the C library for string related functions. In
that case, I know which one to use --- definitely free().

I don't know how experts out there handle this kind of problem. Please
give comments. Thank you.





Author: clamage@Eng.Sun.COM (Steve Clamage)
Date: 1995/07/01
Raw View
jskim@rose.etri.re.kr (Kim Jungsun) writes:

>I have a question about which one to use to deallocate memory which we
>obtained by calling strdup() --- free() or delete. In case of strdup(),
>the user of strdup() have to deallocate a memory. But the problem is that
>there is no way to find out whether strdup() used malloc() or new because
>it is in the library.

strdup() is not part of either the C or C++ standard. Implementors
who provide the function can do it any way they want. You have to
check the documentation for the runtime library, or ask the vendor.
--
Steve Clamage, stephen.clamage@eng.sun.com





Author: imp@village.org (Warner Losh)
Date: 1995/07/03
Raw View
In article <3t2obp$d28@engnews2.eng.sun.com>,
Steve Clamage <clamage@Eng.Sun.COM> wrote:
>strdup() is not part of either the C or C++ standard. Implementors
>who provide the function can do it any way they want. You have to
>check the documentation for the runtime library, or ask the vendor.

While not strictly on topic for this newsgroup:

strdup is a SVID function.  Most people implment this function in 'C'
and uses malloc() for the string.  So, you'd need to use a free() to
deallocate the string.  Most existing code uses free(), so
implementors will likely not break this, but weirder things have
happened.

Warner
--
Warner Losh  "VMS Forever"  home: imp@village.org
Cyberspace Development, Inc   work: imp@marketplace.com
Makers of TIA, The Internet Adapter.  http://marketplace.com/





Author: pardoej@lonnds.ml.com (Julian Pardoe LADS LDN X1428)
Date: 1995/06/29
Raw View
In article <1995Jun24.193118@opal.tufts.edu>, jkauer@opal.tufts.edu (Jonathan Borden) writes:
>> Is this cool?  I.e., if I create an instance using new & then need to
>> make it bigger, can I realloc() it and then safely delete it using
>> delete (or must I use free())?  As always, TIA.
>>
> no, not cool. this is an uuugly hack that might work but never
>absolutely needs to be done. read Coplien's "Advanced C++" (readily available in
>bookstores) for ways to use placement new etc. Often the best way to design
>a class that at first seems like it should be 'variable' length is to create
>a class member which points to a void. This member can be malloc'd, realloc'd
>and free'd. i.e.

BUt that's exactly why having new/delete incompatible with realloc is a major
major pain.  It's a nightmare having to remember whether memory should be
deleted or freed.  I agree that wanting to realloc an object is fairly unusual
but one quite often wants to realloc arrays of basic types or pointers.
It's impossible to remember whether char *x should be deallocated by writing
delete[] x or free (x) so one ends up not being able to use realloc at all,
which is a bit sad and sometimes quite expensive too.

I'd like to see the standard mandate that global new[] and delete[] must be
compatible with malloc/free/realloc.

-- jP --







Author: clamage@Eng.Sun.COM (Steve Clamage)
Date: 1995/06/29
Raw View
In article 7J3@tigadmin.ml.com, pardoej@lonnds.ml.com (Julian Pardoe LADS LDN X1428) writes:
>
>I'd like to see the standard mandate that global new[] and delete[] must be
>compatible with malloc/free/realloc.

The programmer is allowed to replace those functions. The reason for adding
operator new[] and operator delete[] to the language was to satisfy a
requirement to use a special memory pool for arrays. We can't require
that the functions be compatible with malloc/realloc/free and also
allow the use of special memory for arrays.

If you have to remember whether you used new or malloc to get an array,
you have lost control of your program. You shouldn't have to remember.
Allocated memory should have an owner which is responsible for
deallocating it. Each owner should use a consistent strategy.

Using array classes removes the problem entirely.
---
Steve Clamage, stephen.clamage@eng.sun.com







Author: devitto@london.sinet.slb.com (Dom De Vitto)
Date: 1995/06/30
Raw View
Julian Pardoe LADS LDN X1428 (pardoej@lonnds.ml.com) wrote:
> In article <1995Jun24.193118@opal.tufts.edu>, jkauer@opal.tufts.edu (Jonathan Borden) writes:
> >> Is this cool?  I.e., if I create an instance using new & then need to
> >> make it bigger, can I realloc() it and then safely delete it using
> >> delete (or must I use free())?  As always, TIA.
> >>
> > no, not cool. this is an uuugly hack that might work but never
> >absolutely needs to be done. read Coplien's "Advanced C++" (readily available in
> >bookstores) for ways to use placement new etc. Often the best way to design
> >a class that at first seems like it should be 'variable' length is to create
> >a class member which points to a void. This member can be malloc'd, realloc'd
> >and free'd. i.e.

> BUt that's exactly why having new/delete incompatible with realloc is a major
> major pain.  It's a nightmare having to remember whether memory should be
> deleted or freed.  I agree that wanting to realloc an object is fairly unusual
> but one quite often wants to realloc arrays of basic types or pointers.
> It's impossible to remember whether char *x should be deallocated by writing
> delete[] x or free (x) so one ends up not being able to use realloc at all,
> which is a bit sad and sometimes quite expensive too.

> I'd like to see the standard mandate that global new[] and delete[] must be
> compatible with malloc/free/realloc.

I'd like to see C++ compile with K&R function declarations too.
Oh, and I'd like functions automatically have C linkage, then I could just
rename fred.c to fred.cc and be writing C++ programs without reading any
C++ books at all.

C++ *was* C, but it isn't anymore.  Making new/delete malloc/free compatible
would cause a spate of misuses.  You can't realloc an array of objects in the
general case (period), it would make more sense to permit virtual copy
constructors - as this is where the real problem lies......

[ If you really can't be bothered to keep the two forms of allocator
  separate then just write your own global new/delete to use malloc/free. ]

Dom






Author: jkauer@opal.tufts.edu (Jonathan Borden)
Date: 1995/06/30
Raw View
In article <DAxrsJ.7J3@tigadmin.ml.com>, pardoej@lonnds.ml.com (Julian Pardoe LADS LDN X1428) writes:
> In article <1995Jun24.193118@opal.tufts.edu>, jkauer@opal.tufts.edu (Jonathan Borden) writes:
>>> Is this cool?  I.e., if I create an instance using new & then need to
>>> make it bigger, can I realloc() it and then safely delete it using
>>> delete (or must I use free())?  As always, TIA.
>>>
>> no, not cool. this is an uuugly hack that might work but never
>>absolutely needs to be done. read Coplien's "Advanced C++" (readily available in
>>bookstores) for ways to use placement new etc. Often the best way to design
>>a class that at first seems like it should be 'variable' length is to create
>>a class member which points to a void. This member can be malloc'd, realloc'd
>>and free'd. i.e.
>
> BUt that's exactly why having new/delete incompatible with realloc is a major
> major pain.  It's a nightmare having to remember whether memory should be
> deleted or freed.  I agree that wanting to realloc an object is fairly unusual
> but one quite often wants to realloc arrays of basic types or pointers.
> It's impossible to remember whether char *x should be deallocated by writing
> delete[] x or free (x) so one ends up not being able to use realloc at all,
> which is a bit sad and sometimes quite expensive too.
>
> I'd like to see the standard mandate that global new[] and delete[] must be
> compatible with malloc/free/realloc.
>
 I don't think you need this, the draft standard includes STL as
a way to get around this problem in a standard fashion i.e.

 vector<char>, vector<int> etc give you variable length arrays of base
types.
 one of the benefits of using STL is that you shouldn't ever have to
directly call malloc and/or free. In those rare situations in which you may
want to use malloc directly, it is not unreasonable to wrap this up in a class
(such as the one I gave as an example).







Author: jcc@clark.net (John Copella)
Date: 1995/06/23
Raw View
Is this cool?  I.e., if I create an instance using new & then need to
make it bigger, can I realloc() it and then safely delete it using
delete (or must I use free())?  As always, TIA.






Author: kuehl@uzwil (Dietmar Kuehl)
Date: 1995/06/24
Raw View
Hi,

Note that this newsgroup discusses the upcoming C++ Standard not how to
program using C++. Discussion about how to program using C++ belongs
into the group comp.lang.c++.

John Copella (jcc@clark.net) wrote:
: Is this cool?  I.e., if I create an instance using new & then need to
: make it bigger, can I realloc() it and then safely delete it using
: delete (or must I use free())?  As always, TIA.

This is extremely uncool! You should *NEVER* try to 'realloc()' a C++
object or to 'free()' it. See the comp.lang.c++ FAQ (Q33-Q35) for a
more detailed description of what you can do and what not.

If you need to increase the size of an object you should revisit the
design of your program: it is normally an indication that there is
something wrong with you class design.

dk
--
http://www.informatik.uni-konstanz.de/~kuehl
dietmar.kuehl@uni-konstanz.de
I am a realistic optimist - that's why I appear to be slightly pessimistic





Author: jkauer@opal.tufts.edu (Jonathan Borden)
Date: 1995/06/24
Raw View
> Is this cool?  I.e., if I create an instance using new & then need to
> make it bigger, can I realloc() it and then safely delete it using
> delete (or must I use free())?  As always, TIA.
>
 no, not cool. this is an uuugly hack that might work but never
absolutely needs to be done. read Coplien's "Advanced C++" (readily available in
bookstores) for ways to use placement new etc. Often the best way to design
a class that at first seems like it should be 'variable' length is to create
a class member which points to a void. This member can be malloc'd, realloc'd
and free'd. i.e.
 class string
 {
  void * m_pData;
  string(int size){ m_pData = malloc(size); };
  string(const char* pchar){ m_pData = malloc(strlen(pchar));
        strcpy(m_pData,pchar);
      };
  operator const char*(){return (const char*)m_pData;};
  string& operator+(const string& x)
  {
  m_pData = realloc(m_pData,strlen(m_pData)+strlen(x.m_pData));
  strcat(m_pData,x.m_pData);
  };
         ~string(){ free(m_pData); };
 }
     now ... instances of string would be declared on the stack despite the
fact that the actual data is stored on the heap:

 string x = "example";
 string y = " string class";
 outp << x + y << endl;

 example string class


jon borden
jabr technology corporation
component medical software






Author: uchaps00@mcl.ucsb.edu (STEVE E CHAPEL)
Date: 1995/06/24
Raw View
In <3sfb5c$mgk@clarknet.clark.net> jcc@clark.net (John Copella) writes:

>Is this cool?  I.e., if I create an instance using new & then need to
>make it bigger, can I realloc() it and then safely delete it using
>delete (or must I use free())?  As always, TIA.

I wouldn't try this. I don't think it would work on most compilers,
but even if it did compile and run, it would be unsafe.

There is a big difference between new and alloc() or realloc() -
new calls constructors and alloc() and realloc() do not. SImiliarly
delete calls destructors, and free() doee not. Even if you were
able to mix these calls and get your program to work reliably (because
it is not necessary to call the constructor or destructor) your
code might be broken in the future when it IS necessary to call the
constructor and destructor.