Thanks in advance,
Isaac Rodriguez.
malloc() and free() provide raw (uninitialised) memory. When called for a
class, new and delete will call the class' constructor and destructor,
respectively. For example, given:
class foo {
public:
foo();
foo(int);
~foo();
// other details omitted
};
foo_ptr = new foo(1) will allocate memory for a foo object, then call the
constructor that receives an int. If the memory allocation fails, the
std::bad_alloc exception will be thrown.
delete foo_ptr will call the foo's destructor, then release the memory used
by the instance of foo.
foo_array = new [10] foo will allocate an array of 10 foo instances,
initialising them with the default constructor.
delete [] foo_array will call the destrutor for each instance of foo in the
array, then release the memory.
in contrast, foo_ptr = malloc(sizeof(foo)) will allocate memory for a foo
object, but will not initialise it. free(foo_ptr) will not call the foo
destructor before releasing the memory. the two mechanisms should _NEVER_ be
mixed!
Daniel Pfeffer
If you're writing C, use malloc/free.
If you're writing C++, use new/delete or new[]/delete[]
And for that 0.1% of the time when you're writing C++ and you find yourself
needing to use malloc:
Never mix malloc/free with new/delete
ie, if you allocated with malloc, dealloc with free; if you allocated with
new, use delete to deallocate.
Richard
Jeroen
"Richard@UCSD" <co...@san.rr.com> wrote in message news:394d4401@dnews...
> On top of what Daniel said, a good rule of thumb that works 99.9% of the
> time (would say 100 but I'm sure someone could think of some reason that
> would invalidate this rule for 0.1% of the time...maybe):
>
> If you're writing C, use malloc/free.
> If you're writing C++, use new/delete or new[]/delete[]
There is one case where it is common to use malloc in a C++ program,
and that is if you're overloading operator new. If you're writing
operator new, how does it acquire memory without recursively calling
itself? Well, you could call global new, but if you're not
careful..... you could cause a recursive infinite loop.
--
Chris (TeamB);
Richard
>The only reason I ever use malloc is the availability of a realloc. It's
>of course very easy to make your own realloc type of function for a
>new/delete array, but my assumption is that realloc is a fairly tightly
>optimised asm-function.
One should also avoid dealing with raw arrays, and use STL containers
instead for their greater safety. Then you get a reallocator for free.
Don't use malloc/free/realloc until profiling demonstrates that they're
indespensible. Don't optimize too early.
>"Isaac Rodriguez" <ms...@earthlink.net> wrote in message
>news:8iislj$3b...@bornews.borland.com...
>> Hi, I would like to know what are the most important differences between
>> memory allocation using malloc and free vs. new and delete. I've heard
>that
>> new and delete work better but I don't understand why. What is going on
>> behind the scenes when you use malloc and when you use new? Which
>advantages
>> has new over malloc? and what disadvantages?
>
>malloc() and free() provide raw (uninitialised) memory. When called for a
>class, new and delete will call the class' constructor and destructor,
>respectively. For example, given:
>
>class foo {
>public:
> foo();
> foo(int);
> ~foo();
>
> // other details omitted
>};
>
new is part of the class, and returns the right type so you won't need
typecasting. It also calls the constructor. It's easier to read too.
And you can't use malloc on classes, you must use new.
>foo_ptr = new foo(1) will allocate memory for a foo object, then call the
>constructor that receives an int. If the memory allocation fails, the
>std::bad_alloc exception will be thrown.
Thanks to a compiler (or rtl) bug, no exception will be thrown.
Instead your program will crash.
------------------------------------------------------
--
Martin
If you write
T* pt = new T;
'new T' is a new expression. This will first call 'operator new()' and,
in case it succeeds, 'T's constructor. The operator new is overloadeable,
thus you can roll your own. The built in one will throw an exception
on errors, thus you cannot miss an error. The call to the constructor
makes sure your object is initialized before you use it, thus you cannot
use uninitialized objects.
All these are important parts of the C++ universe.
> Isaac Rodriguez.
Schobi
--
Spam...@gmx.de is never read
I'm hschober at gmx dot de
That's what you think. Try it. You'll find another compiler bug.
btw a user-defined new-handler doesn't work either.
--
Martin
I don't think there is a bug there. Please explain what you mean.
Also, please describe "doesn't work" in reference to a user defined
new-handler.
--
Chris (TeamB);
>cha...@xs4all.nl (martin) writes:
>
>> > The built in one will throw an exception
>> > on errors, thus you cannot miss an error.
>>
>> That's what you think. Try it. You'll find another compiler bug.
>> btw a user-defined new-handler doesn't work either.
>
>I don't think there is a bug there. Please explain what you mean.
try a new char[20000000000], this should fail, and throw an exception,
right ? In BCB it doesn't.
>Also, please describe "doesn't work" in reference to a user defined
>new-handler.
Exactly what I say : it doesn't work. It does nothing.
There's also a way to have new return NULL when it fails. That doesn't
work either (meaning it's doesn't return NULL when it fails).
--
Martin
Loke
How do you define "fail"?
int main()
{
new char[20000000000];
}
produces:
bash-2.02$ ./newchar20000000000.exe
Abnormal program termination
#include <iostream>
#include <new>
int main()
{
try {
new char[20000000000];
}
catch (std::bad_alloc &)
{
std::cout << "caught bad_alloc\n";
}
}
produces:
bash-2.02$ ./newchar20000000000.exe
caught bad_alloc
>try a new char[20000000000], this should fail, and throw an exception,
>right ? In BCB it doesn't.
It does on my system:
------------ test.cpp -------------
#include <iostream>
using std::cout ;
int main()
{
try
{
char * foo = new char[20000000000] ;
}
catch(...)
{
cout << "Exception caught" ;
}
}
------------ test.cpp -------------
C:\>bcc32 test
Borland C++ 5.5 for Win32 Copyright (c) 1993, 2000 Borland
test.cpp:
Warning W8004 test.cpp 10: 'foo' is assigned a value that is never used
in function main()
Turbo Incremental Link 5.00 Copyright (c) 1997, 2000 Borland
C:\>test
Exception caught
C:\>
-------------------------
That works fine on my system, as you can see.
Now, if you've managed to corrupt the memory manager, something else may
happen.
Alan Bellingham
--
al...@episys.com
For book reviews and much more, see the Association of C and C++ Users
website at http://www.accu.org
>try a new char[20000000000], this should fail, and throw an exception,
>right ? In BCB it doesn't.
Well, it depends on a few factors:
(1) How much virtual memory is available.
(2) The size *actually* being requested, after truncation.
(3) If the "size" type used with "new" is a 32-bit unsigned type,
then the max value possible is 4,294,967,295 bytes. Since
you're trying to stuff 20,000,000,000 into it, the value gets
truncated to 2,820,130,820 and the request *may* be
satisfied, if enough virtual memory is available.
--
Wayne A. King
(ba...@torfree.net, wayne...@ablelink.org,
wak...@idirect.com, Wayne_...@compuserve.com)
>martin wrote:
>>
>> try a new char[20000000000], this should fail, and throw an exception,
>> right ? In BCB it doesn't.
>
>How do you define "fail"?
Oh, come on. You're not that stupid, are you ?
>int main()
>{
> new char[20000000000];
>}
>
>produces:
>
>bash-2.02$ ./newchar20000000000.exe
>Abnormal program termination
>
>
>#include <iostream>
>#include <new>
>
>int main()
>{
> try {
> new char[20000000000];
> }
> catch (std::bad_alloc &)
> {
> std::cout << "caught bad_alloc\n";
> }
>}
>
>produces:
>
>bash-2.02$ ./newchar20000000000.exe
>caught bad_alloc
This is a borland c++ builder newsgroup, and I was talking about
compiler bugs, not language bugs.
--
Martin
It appears they fixed it in Builder 5. I should have mentioned I was
using Builder 4 when I was testing this :)
--
Martin
------------------------------------------------------------------
C:\>set path=c:\program files\borland\cbuilder3\bin
C:\>bcc32 test.cpp
Borland C++ 5.3 for Win32 Copyright (c) 1993, 1998 Borland International
test.cpp:
Warning test.cpp 10: 'foo' is assigned a value that is never used in
function main()
Turbo Incremental Link 3.0 Copyright (c) 1997, 1998 Borland
International
C:\>test
Exception caught
C:\>
------------------------------------------------------------------
Must have been a bug they introduced for BCB4 and then fixed again. I
never actually compiled anything real with BCB4, so I'll leave it to
others.
and, later:
> This is a borland c++ builder newsgroup, and I was talking about
> compiler bugs, not language bugs.
How do you define "stupid"?
You wrote that the program, compiled by BCB, should throw an exception. I
showed you that it does. Who's stupid now?
BTW, what's a "language bug"?
> On Thu, 22 Jun 2000 16:18:16 +0200, Thomas Maeder <mae...@glue.ch>
> wrote :
>
> >martin wrote:
> >>
> >> try a new char[20000000000], this should fail, and throw an exception,
> >> right ? In BCB it doesn't.
> >
> >How do you define "fail"?
>
> Oh, come on. You're not that stupid, are you ?
It's a VERY reasonable question. People frequently operate with
different definitions, and something to you may "fail" because you
expect one thing, but to me they do not fail because they are
operating as I expect them.
Frequently "fail" is a catch-all term that is, at best, vague.
You said that two actions should occur whn you try to allocate a huge
buffer that is greater than available memory:
1) fail
2) throw exception
I do not know what you mean by saying it should fail AND throw an
exception. Are these two seperate actions? If so, what behavior
should be displayed when it "fails"? Is throwing the exception in
addition to failing, or a result of failing?
While I know how it is supposed to behave in error conditions, by the
statement posted, it's not clear if you understand it. I suspect that
is why he asked for you to explicitly provide your definition.
> >bash-2.02$ ./newchar20000000000.exe
> >Abnormal program termination
> >bash-2.02$ ./newchar20000000000.exe
> >caught bad_alloc
> This is a borland c++ builder newsgroup, and I was talking about
> compiler bugs, not language bugs.
This is a C++ Builder newsgroup, true. (What does that have to do
with the discussion though? (???) Bash has been ported to windows for
years now...
I still do not know WHAT bug you are talking about. You say there is
"a bug" but don't say what it is or describe it. Then when someone
asks for clairification you call him stupid. Please consider the
situation again with a little less hostility for those trying to help
you. The behavior you're apparently expecting is what I see.
Obviously there is some communication breakdown here, so start over,
and be *** SPECIFIC ***. Thanks.
--
Chris (TeamB);
> "Richard@UCSD" <co...@san.rr.com> writes:
>
> > On top of what Daniel said, a good rule of thumb that works 99.9% of the
> > time (would say 100 but I'm sure someone could think of some reason that
> > would invalidate this rule for 0.1% of the time...maybe):
> >
> > If you're writing C, use malloc/free.
> > If you're writing C++, use new/delete or new[]/delete[]
>
> There is one case where it is common to use malloc in a C++ program,
> and that is if you're overloading operator new. If you're writing
> operator new, how does it acquire memory without recursively calling
> itself? Well, you could call global new, but if you're not
> careful..... you could cause a recursive infinite loop.
>
Sort of. A class can provide an operator new() which in turn calls
the global operator new() ("operator new()" is a function that
is called to allocate raw memory before constructors are invoked
in a statement like Object *x = new Object[10];). If a class
does not provide it's own operator new(), the default action
is calling the global operator new().
If you need to override the global operator new, you may make
it invoke malloc(). This is fairly non-portable between compilers
(eg although highly unlikely, a compiler or library vendor is allowed
to implement malloc in terms of the global operator new()).
However, most programs that need to override the global
operator new are highly non-portable anyway (eg because they
need to access particular hardware).
One other area in C++ where using malloc/free instead of new/delete
makes no difference is with structs that don't provide any member
functions (or constructors, destructors, etc). Particularly
if those declarations are wrapped in extern "C". This is one thing
that makes reuse of existing C code in C++ more practical.