whats the advantageof malloc over new in c++. – C / C++

  c

Q(Question):

whats the beauty of "malloc" over "new" why its helpful for
programmer.for its own memory area.??

A(Answer):

On 19 Aug, 09:52, Muzammil <muzammilPeer…@gmail.comwrote:

whats the beauty of "malloc" over "new" why its helpful for
programmer.for *its own memory area.??

malloc() doesn’t get used in C++ programs very much.
malloc() just allocates memory. new allocates memory
and constructs the object (by calling the constructor).
Placement new runs the constructor on the memory provided.

malloc() is mainly provided for historical compatibility
with C. new may use malloc() internally (it doesn’t have to).

the main use for malloc(), I can see, is if memory is to
be passed to a C function and to be freed by the C function.

Nick Keighley

A(Answer):

On Aug 19, 5:57 pm, Nick Keighley <nick_keighley_nos…@hotmail.com>
wrote:

On 19 Aug, 09:52, Muzammil <muzammilPeer…@gmail.comwrote:

whats the beauty of "malloc" over "new" why its helpful for
programmer.for its own memory area.??

malloc() doesn’t get used in C++ programs very much.
malloc() just allocates memory. new allocates memory
and constructs the object (by calling the constructor).
Placement new runs the constructor on the memory provided.

malloc() is mainly provided for historical compatibility
with C. new may use malloc() internally (it doesn’t have to).

the main use for malloc(), I can see, is if memory is to
be passed to a C function and to be freed by the C function.

+ malloc provides memory that _may_ be able to be grown using
realloc() without having to copy the content

+ new can be overridden to do all manner of things – which is normally
a good thing – but malloc() might occasionally be useful as a way to
bypass this (though you can’t generally be sure that the "normal"
malloc function will receive your call – there are lots of ways of
installing alternatives)

+ you can free malloced memory without having the destructor called
(not normally a good idea, but may allow optimisations in certain
usages)

Still, the short story is don’t use malloc/realloc and free unless you
find a reason to have to.

Tony

A(Answer):

On 2008-08-19 11:57, to***********@yahoo.co.uk wrote:

On Aug 19, 5:57 pm, Nick Keighley <nick_keighley_nos…@hotmail.com>
wrote:

>On 19 Aug, 09:52, Muzammil <muzammilPeer…@gmail.comwrote:

whats the beauty of "malloc" over "new" why its helpful for
programmer.for its own memory area.??

malloc() doesn’t get used in C++ programs very much.
malloc() just allocates memory. new allocates memory
and constructs the object (by calling the constructor).
Placement new runs the constructor on the memory provided.

malloc() is mainly provided for historical compatibility
with C. new may use malloc() internally (it doesn’t have to).

the main use for malloc(), I can see, is if memory is to
be passed to a C function and to be freed by the C function.

+ malloc provides memory that _may_ be able to be grown using
realloc() without having to copy the content

Provided that the content of that memory does not have to be constructed.


Erik Wikstrâm

A(Answer):

Erik Wikstrâm wrote:

>+ malloc provides memory that _may_ be able to be grown using
realloc() without having to copy the content

Provided that the content of that memory does not have to be constructed.

You could always use placement new to construct that memory. (OTOH if
you must construct it, it starts making little sense to not to just use
‘new’ rather than ‘malloc’.)

A(Answer):

"Muzammil" <mu*************@gmail.comwrote in message news:b1**********************************@56g2000h sm.googlegroups.com…

whats the beauty of "malloc" over "new" why its helpful for
programmer.for its own memory area.??

memory allocated by malloc can be reallocated with realloc.
malloc doesnt throw an exception if the allocation fails.
Most runtimes implement a rich set of heap interrogation / debugging methods that can be usefull, which work principally on memory allocated with malloc.

A(Answer):

On 19 Aug., 11:59, "Chris Becke" <chris.be…@gmail.comwrote:

"Muzammil" <muzammilPeer…@gmail.comwrote in messagenews:b1**********************************@5 6g2000hsm.googlegroups.com…

whats the beauty of "malloc" over "new" why its helpful for
programmer.for *its own memory area.??

memory allocated by malloc can be reallocated with realloc.

But this is not really useful in a C++ context.

malloc doesnt throw an exception if the allocation fails.

Neither does new if you use the nothrow version (although I’ve
difficulties finding places, where I’d care about that).

Most runtimes implement a rich set of heap interrogation / debugging methods that can be
usefull, which work principally on memory allocated with malloc.

You can always base new on malloc if you want to – this allows you to
use the exact same methods, should they not already be available for
new/delete.
/Peter

A(Answer):

On 19 Aug., 10:52, Muzammil <muzammilPeer…@gmail.comwrote:

whats the beauty of "malloc" over "new" why its helpful for
programmer.for *its own memory area.??

The only reason to use malloc is for interfacing with C.

/Peter

A(Answer):

Chris Becke wrote:

"Muzammil" <mu*************@gmail.comwrote in message
news:b1**********************************@56g2000h sm.googlegroups.com…

>whats the beauty of "malloc" over "new" why its helpful for
programmer.for its own memory area.??

memory allocated by malloc can be reallocated with realloc.

Which just sometimes might realloc in place, otherwise it has to copy
everything. And this doesn’t work for anything with a constructor.

malloc doesnt throw an exception if the allocation fails.

A clear disadvantage. πŸ™‚

You have to check the result manually instead.

Most runtimes implement a rich set of heap interrogation /
debugging methods that can be usefull, which work principally on
memory allocated with malloc.

If you use std::vector you probably will never have to debug the
memory allocation at all.
Bo Persson

A(Answer):

On Aug 20, 6:02 am, "Bo Persson" <b…@gmb.dkwrote:

Chris Becke wrote:

"Muzammil" <muzammilPeer…@gmail.comwrote in message
news:b1**********************************@56g2000h sm.googlegroups.com…

whats the beauty of "malloc" over "new" why its helpful for
programmer.for its own memory area.??

memory allocated by malloc can be reallocated with realloc.

Which just sometimes might realloc in place, otherwise it has to copy
everything. And this doesn’t work for anything with a constructor.

"just sometimes might" is trivialising the benefit a bit ;-). Anyway,
only the additional elements need then be manually constructed with
placement new… and this doesn’t necessarily need to be done using a
default constructor before the meaningful values are available which
can be an advantage… so at least this two-step process can work for
some things with constructors.

Perhaps a bigger issue is that moved existing elements aren’t copy
constructed so references/pointers stored therein may end up invalid.

Tony

A(Answer):

On 20 Aug., 02:07, tony_in_da…@yahoo.co.uk wrote:

On Aug 20, 6:02 am, "Bo Persson" <b…@gmb.dkwrote:

Chris Becke wrote:

"Muzammil" <muzammilPeer…@gmail.comwrote in message
>news:b1**********************************@56g2000 hsm.googlegroups.com….
>whats the beauty of "malloc" over "new" why its helpful for
>programmer.for *its own memory area.??

memory allocated by malloc can be reallocated with realloc.

Which just sometimes might realloc in place, otherwise it has to copy
everything. And this doesn’t work for anything with a constructor.

"just sometimes might" is trivialising the benefit a bit ;-). *Anyway,
only the additional elements need then be manually constructed with
placement new… and this doesn’t necessarily need to be done using a
default constructor before the meaningful values are available which
can be an advantage… so at least this two-step process can work for
some things with constructors.

Perhaps a bigger issue is that moved existing elements aren’t copy
constructed so references/pointers stored therein may end up invalid.

Tony

If you are depending on the realloc-trick, most probably you are
implementing an array. In that case, std::vector is the place to go.
std::vector can take of advantage of whatever low-level memory
management the platform has and do an "in-place realloc" if such a
beast exists.

/Peter

A(Answer):

On Aug 20, 9:53 am, peter koch <peter.koch.lar…@gmail.comwrote:

On 20 Aug., 02:07, tony_in_da…@yahoo.co.uk wrote:

On Aug 20, 6:02 am, "Bo Persson" <b…@gmb.dkwrote:

Chris Becke wrote:
"Muzammil" <muzammilPeer…@gmail.comwrote in message
news:b1**********************************@56g2000h sm.googlegroups.com…
whats the beauty of "malloc" over "new" why its helpful for
programmer.for its own memory area.??

memory allocated by malloc can be reallocated with realloc.

Which just sometimes might realloc in place, otherwise it has to copy
everything. And this doesn’t work for anything with a constructor.

"just sometimes might" is trivialising the benefit a bit ;-). Anyway,
only the additional elements need then be manually constructed with
placement new… and this doesn’t necessarily need to be done using a
default constructor before the meaningful values are available which
can be an advantage… so at least this two-step process can work for
some things with constructors.

Perhaps a bigger issue is that moved existing elements aren’t copy
constructed so references/pointers stored therein may end up invalid.

Tony

If you are depending on the realloc-trick, most probably you are
implementing an array. In that case, std::vector is the place to go.
std::vector can take of advantage of whatever low-level memory
management the platform has and do an "in-place realloc" if such a
beast exists.

/Peter

This should help.

http://www.parashift.com/c++-faq-lit….html#faq-16.4

Sumanth

A(Answer):

peter koch wrote:

The only reason to use malloc is for interfacing with C.

Well, I can imagine a custom allocator using malloc rather than new
because the former allocates uninitialized memory, which is exactly what
a custom allocator should do (it’s up to the calling code to actually
initialize the allocated memory).

A(Answer):

to***********@yahoo.co.uk wrote:

On Aug 20, 6:02 am, "Bo Persson" <b…@gmb.dkwrote:

>Chris Becke wrote:

>>"Muzammil" <muzammilPeer…@gmail.comwrote in message
news:b1**********************************@56g200 0hsm.googlegroups.com…
whats the beauty of "malloc" over "new" why its helpful for
programmer.for its own memory area.??

>>memory allocated by malloc can be reallocated with realloc.

Which just sometimes might realloc in place, otherwise it has to
copy everything. And this doesn’t work for anything with a
constructor.

"just sometimes might" is trivialising the benefit a bit ;-).

Yes.

The problem is that you don’t know whether it works or not. If it is
important to realloc very fast, you have to make sure it works. If it
isn’t important, it just isn’t.

Anyway, only the additional elements need then be manually
constructed with placement new… and this doesn’t necessarily need
to be done using a default constructor before the meaningful values
are available which can be an advantage… so at least this
two-step process can work for some things with constructors.

But realloc() takes a void* pointer to the memory block, so it doesn’t
know what kind of objects it contains.

>
Perhaps a bigger issue is that moved existing elements aren’t copy
constructed so references/pointers stored therein may end up
invalid.

Rather important, yes. πŸ™‚
Bo Persson

A(Answer):

On 20 Aug., 17:08, Juha Nieminen <nos…@thanks.invalidwrote:

peter koch wrote:

The only reason to use malloc is for interfacing with C.

* Well, I can imagine a custom allocator using malloc rather than new
because the former allocates uninitialized memory, which is exactly what
a custom allocator should do (it’s up to the calling code to actually
initialize the allocated memory).

In this case operator new serves just as well.

/Peter

A(Answer):

On Aug 21, 1:51*am, "Bo Persson" <b…@gmb.dkwrote:

tony_in_da…@yahoo.co.uk wrote:

Anyway, only the additional elements need then be manually
constructed with placement new… and this doesn’t necessarily need
to be done using a default constructor before the meaningful values
are available which can be an advantage… so at least this
two-step process can work for some things with constructors.

But realloc() takes a void* pointer to the memory block, so it doesn’t
know what kind of objects it contains.

Perhaps I didn’t explain that well… sorry… off-the-top-of-my head
coding here:

if (X* p = (X*)realloc(old_p, sizeof(X) * new_capacity))
for (int n = old_size; n < new_capacity; ++n)
new(p[n]) X(fn(n)); // meaningful construction…

Cheers,
Tony

A(Answer):

A clear disadvantage. πŸ™‚

You have to check the result manually instead.

predictable program flow is a disadvantage? Not even google likes c++ exceptions.

A(Answer):

Chris Becke wrote:

>A clear disadvantage. πŸ™‚

You have to check the result manually instead.

predictable program flow is a disadvantage? Not even google likes c++ exceptions.

Their loss.


Ian Collins.

A(Answer):

In article <bd**********************************@x16g2000prn. googlegroups.com>,
<to***********@yahoo.co.ukwrote:

>On Aug 21, 1:51*am, "Bo Persson" <b…@gmb.dkwrote:

>tony_in_da…@yahoo.co.uk wrote:

Anyway, only the additional elements need then be manually
constructed with placement new… and this doesn’t necessarily need
to be done using a default constructor before the meaningful values
are available which can be an advantage… so at least this
two-step process can work for some things with constructors.

But realloc() takes a void* pointer to the memory block, so it doesn’t
know what kind of objects it contains.

Perhaps I didn’t explain that well… sorry… off-the-top-of-my head
coding here:

if (X* p = (X*)realloc(old_p, sizeof(X) * new_capacity))
for (int n = old_size; n < new_capacity; ++n)
new(p[n]) X(fn(n)); // meaningful construction…

Hmm, tell me what happens in the code above if realloc unfortunately
fail to be able to grow in place and need to malloc new memory at a
different place?

Guess if X is memcpy-able you’ll survive but if not, you are dead.

What advantage does this has over (apart from being more bug prone):

std:vector<Xv;
// v.reserve(somenumber); //optional
// …
for(size_t n = v.size(); v < nerw_capacity ; ++v)
v.append(X(f(n)));
Yan

A(Answer):

On 21 Aug., 09:26, "Chris Becke" <chris.be…@gmail.comwrote:

A clear disadvantage. *:-)

You have to check the result manually instead.

predictable program flow is a disadvantage? Not even google likes c++ exceptions.

I don’t know about google, but using an exception is the preferred and
standard way to cope with an error that can’t be handled locally. If
you believe that you can handle the exception locally, nothing
prevents you from using the non-throwing version of new.

/Peter

A(Answer):

On Aug 21, 9:13 pm, ytrem…@nyx.nyx.net (Yannick Tremblay) wrote:

In article <bd7a4e3f-0781-4441-af02-f3976675e…@x16g2000prn.googlegroups.com>,

<tony_in_da…@yahoo.co.ukwrote:

On Aug 21, 1:51 am, "Bo Persson" <b…@gmb.dkwrote:

tony_in_da…@yahoo.co.uk wrote:
Anyway, only the additional elements need then be manually
constructed with placement new… and this doesn’t necessarily need
to be done using a default constructor before the meaningful values
are available which can be an advantage… so at least this
two-step process can work for some things with constructors.

But realloc() takes a void* pointer to the memory block, so it doesn’t
know what kind of objects it contains.

Perhaps I didn’t explain that well… sorry… off-the-top-of-my head
coding here:

if (X* p = (X*)realloc(old_p, sizeof(X) * new_capacity))
for (int n = old_size; n < new_capacity; ++n)
new(p[n]) X(fn(n)); // meaningful construction…

Hmm, tell me what happens in the code above if realloc unfortunately
fail to be able to grow in place and need to malloc new memory at a
different place?

Guess if X is memcpy-able you’ll survive but if not, you are dead.

Agreed – discussed earlier in another of my posts to this thread.

What advantage does this has over (apart from being more bug prone):

std:vector<Xv;
// v.reserve(somenumber); //optional
// …
for(size_t n = v.size(); v < nerw_capacity ; ++v)
v.append(X(f(n)));

Yan

The advantage (strange that you list error proneness as an advantage)
that I was discussed was that you’re making a more explicit request
that the vector not be moved unless necessary.

You seem to be misunderstanding my posts… we’re not recommending
these usages, but explaining differences and why sometimes some
vaguely credible excuse/argument for using malloc/realloc/free exists.

Tony

A(Answer):

In article <05**********************************@79g2000hsk.g ooglegroups.com>,
<to***********@yahoo.co.ukwrote:

>On Aug 21, 9:13 pm, ytrem…@nyx.nyx.net (Yannick Tremblay) wrote:

>In article

<bd7a4e3f-0781-4441-af02-f3976675e…@x16g2000prn.googlegroups.com>,

>>
<tony_in_da…@yahoo.co.ukwrote:

>if (X* p = (X*)realloc(old_p, sizeof(X) * new_capacity))
for (int n = old_size; n < new_capacity; ++n)
new(p[n]) X(fn(n)); // meaningful construction…

Hmm, tell me what happens in the code above if realloc unfortunately
fail to be able to grow in place and need to malloc new memory at a
different place?

Guess if X is memcpy-able you’ll survive but if not, you are dead.

Agreed – discussed earlier in another of my posts to this thread.

>What advantage does this has over (apart from being more bug prone):

std:vector<Xv;
// v.reserve(somenumber); //optional
// …
for(size_t n = v.size(); v < nerw_capacity ; ++v)
v.append(X(f(n)));

Yan

The advantage (strange that you list error proneness as an advantage)

Sorry, a smiley should have been added. That was an attempt at irony.

>that I was discussed was that you’re making a more explicit request
that the vector not be moved unless necessary.

(which is exactly what std::vector does)
The problem is that you do not know in advance if the realloc can
grow the buffer or if it will need to malloc and copy. Either can
happen. This makes the construct pointless. Worse, it gives the
illusion to the poor programmer that the memory will not be moved and
it hides bugs.

>You seem to be misunderstanding my posts… we’re not recommending
these usages, but explaining differences and why sometimes some
vaguely credible excuse/argument for using malloc/realloc/free exists.

But my point was this is not even a vaguely credible excuse. It is
simply WRONG. std::vector will do the right thing. It will probably
internally try to grow its buffer and not move it unless necessary.
If you use reserve, it will not need to move/copy. If you didn’t or
grow beyond the originally reserved size, if it can grow its buffer,
its performance characteristics will be similar to the use of realloc,
if it can’t grow in place, it will copy correctly.

It is not a question of not recommending using realloc with objects.
It should be actively recommended against.

Essentially, to go back to the subject of this thread:

If you write C++ use new.
(you can stop reading here)

There are very few reasons to use malloc in C++. Most of the excuses
given by poor programmers to use malloc are incorrect overlooking a
few issues.

If you really really think you must use malloc, only do it with basic
POD-types. The most valid reason I can think of is that you must
allocate memory that will be passed to _and_ freed by a C module. If
that’s the case,then it must be POD anyway.

Although it is possible to malloc and use placement new, don’t do it.
It’s not worth it. You are likely lying to yourself about the
benefits, you are likely to fall into a trap, you would be writing
unmaintainable software.

If you still really really think that you must use malloc for C++
objects, think about it again, find a better C++ programmer than you
and show him your design and proposed code and ask him to help you
find a better solution. If the guru can’t find a better way, make sure
he is really a C++ guru and a good software developper. If that’s the
case, then maybe, just maybe you found the exception that confirms the
rule.

Yannick
P.S.:
sorry for the preaching but I’ve had the unfortunate experience of
working with bad programmers in my life. Bad C programmers having
moved to C++ insisting on using malloc because it’s what they’ve
always used. Doing awful premature optimisation without profiling.
Wanting to use malloc/realloc because "C++ is slow and does things
under the hood without telling you" without having profiled nor
bothered looking at std::vector implementation.

A(Answer):

On Aug 21, 2:46*am, Ian Collins <ian-n…@hotmail.comwrote:

Chris Becke wrote:

A clear disadvantage. *:-)

You have to check the result manually instead.

predictable program flow is a disadvantage? Not even google likes c++ exceptions.

Their loss.


Ian Collins.

Ian

To make the discussion concrete, it might be interesting to address
the Cons mentioned at this link:
http://google-styleguide.googlecode….ons#Exceptions

It does look like Google is simply talking about difficulty of
introducing exceptions in an existing codebase and they do agree that
their benefits far outweigh the costs.

A(Answer):

Dilip wrote:

On Aug 21, 2:46 am, Ian Collins <ian-n…@hotmail.comwrote:

>Chris Becke wrote:

>>>A clear disadvantage. πŸ™‚
You have to check the result manually instead.
predictable program flow is a disadvantage? Not even google likes c++ exceptions.

Their loss.

Ian

To make the discussion concrete, it might be interesting to address
the Cons mentioned at this link:
http://google-styleguide.googlecode….ons#Exceptions

It does look like Google is simply talking about difficulty of
introducing exceptions in an existing codebase and they do agree that
their benefits far outweigh the costs.

In that context their rule does make sense.


Ian Collins.

A(Answer):

On Aug 22, 6:36*pm, ytrem…@nyx.nyx.net (Yannick Tremblay) wrote:

In article <05c12633-ec68-489a-afcf-25beadbb8…@79g2000hsk.googlegroups.com>,

*<tony_in_da…@yahoo.co.ukwrote:
if (X* p = (X*)realloc(old_p, sizeof(X) * new_capacity))
* *for (int n = old_size; n < new_capacity; ++n)
* * * *new(p[n]) X(fn(n)); // meaningful construction…

What advantage does this has over (apart from being more bug prone):

std:vector<Xv;
// v.reserve(somenumber); //optional
// …
for(size_t n = v.size(); v < nerw_capacity ; ++v)
* * v.append(X(f(n)));

[realloc advantage] you’re making a more explicit request
that the vector not be moved unless necessary.

(which is exactly what std::vector does)
The problem is that you do not know in advance if the realloc can
grow the buffer or if it will need to malloc and copy. *Either can
happen. *This makes the construct pointless. *Worse, *it gives the
illusion to the poor programmer that the memory will not be moved and
it hides bugs. *

I think this is the second time in this thread that the "can’t be sure
= useless" argument has been put. It’s blatantly absurd: for example,
is a hash_map useless because it might have a collision? Laws of
averages are relevant.

Re may-or-may-not introducing two code paths to test / hides bugs:
agreed – using malloc/realloc/free is definitely much more fraught
with risks than new/delete. That’s not really relevant either, as I’m
saying realloc has one potential advantage – you can be sure if will
realloc in-place if possible – not defending the overall balance of
pros and cons.

You seem to be misunderstanding my posts… we’re not recommending
these usages, but explaining differences and why sometimes some
vaguely credible excuse/argument for using malloc/realloc/free exists.

But my point was this is not even a vaguely credible excuse. *It is
simply WRONG. *std::vector will do the right thing. *It will probably
internally try to grow its buffer and not move it unless necessary.

"Proabably"? What gives you this idea? The old SGI STL provided a
hint to the allocator which could be used for this, but to the best of
my knowledge this is not common practice in current STL
implementations, it’s not available in the GCC headers shipped with
the current Dev-C++ (sorry / no real machine to check handy), and the
Oct ’97 draft Standard section 20.1.5.2 Table 6 makes it clear that
there’s no expectation of any support for realloc or the SGI-style
hint.

If you use reserve, it will not need to move/copy.
If you didn’t or
grow beyond the originally reserved size, if it can grow its buffer,
its performance characteristics will be similar to the use of realloc,
if it can’t grow in place, it will copy correctly.

Yes, but often not possible (e.g. when appending elements as they
arrive from an IPC mechanism, or are entered by a user).

It is not a question of not recommending using realloc with objects.
It should be actively recommended against. *

Yes, I believe I’ve done that already "Still, the short story is don’t
use malloc/realloc and free unless you find a reason to have to.".
That doesn’t mean that the pros/cons can’t be objectively enumerated
and weighed.

Essentially, to go back to the subject of this thread:

If you write C++ use new. *
(you can stop reading here)

Pretty much right. Anyone experienced enough to understand that they
really must use new doesn’t need to read this thread anyway….

sorry for the preaching but I’ve had the unfortunate experience of
working with bad programmers in my life. *Bad C programmers having
moved to C++ insisting on using malloc because it’s what they’ve
always used. *Doing awful premature optimisation without profiling.
Wanting to use malloc/realloc because "C++ is slow and does things
under the hood without telling you" without having profiled nor
bothered looking at std::vector implementation. *

Yes, part of being a programmer… quite understand.

Cheers,

Tony

A(Answer):

In article <3b**********************************@b2g2000prf.g ooglegroups.com>,
<to***********@yahoo.co.ukwrote:

>On Aug 22, 6:36*pm, ytrem…@nyx.nyx.net (Yannick Tremblay) wrote:

>In article <05c12633-ec68-489a-afcf-25beadbb8…@79g2000hsk.googlegroups.com>,

>*<tony_in_da…@yahoo.co.ukwrote:
if (X* p = (X*)realloc(old_p, sizeof(X) * new_capacity))
* *for (int n = old_size; n < new_capacity; ++n)
* * * *new(p[n]) X(fn(n)); // meaningful construction…

>What advantage does this has over (apart from being more bug prone):

>std:vector<Xv;
// v.reserve(somenumber); //optional
// …
for(size_t n = v.size(); v < nerw_capacity ; ++v)
* * v.append(X(f(n)));

[should have been push_back(), sorry]

>[realloc advantage] you’re making a more explicit request
that the vector not be moved unless necessary.

(which is exactly what std::vector does)
The problem is that you do not know in advance if the realloc can
grow the buffer or if it will need to malloc and copy. *Either can
happen. *This makes the construct pointless. *Worse, *it gives the
illusion to the poor programmer that the memory will not be moved and
it hides bugs. *

I think this is the second time in this thread that the "can’t be sure
= useless" argument has been put. It’s blatantly absurd: for example,
is a hash_map useless because it might have a collision? Laws of
averages are relevant.

There’s a huge difference between hash_map collisions and failure of
realloc to grow in place in the code above: a hash_map is designed to
handle hash collision, a collision simply result in slightly slower
access time. In the sample code above, realloc deciding that it needs
to move everything elsewhere and memcpy results in a bug! That is not
comparable. Law of average should not be used if it mean that "most
of the time my program will work but once in a while it will crash"
rather than "most of the time my program will be fast but once in a
while it will get a bit slower".

>Re may-or-may-not introducing two code paths to test / hides bugs:
agreed – using malloc/realloc/free is definitely much more fraught
with risks than new/delete. That’s not really relevant either, as I’m
saying realloc has one potential advantage – you can be sure if will
realloc in-place if possible – not defending the overall balance of
pros and cons.

You can be sure that if it is possible it will realoc in place
but you can’t know "if it is possible". So essentially, you know
nothing and you are sure of nothing.

>But my point was this is not even a vaguely credible excuse. *It is
simply WRONG. *std::vector will do the right thing. *It will probably
internally try to grow its buffer and not move it unless necessary.

"Proabably"? What gives you this idea? The old SGI STL provided a
hint to the allocator which could be used for this, but to the best of
my knowledge this is not common practice in current STL
implementations, it’s not available in the GCC headers shipped with
the current Dev-C++ (sorry / no real machine to check handy), and the
Oct ’97 draft Standard section 20.1.5.2 Table 6 makes it clear that
there’s no expectation of any support for realloc or the SGI-style
hint.

Sorry, you are right, my implementation appears to move the buffer
(and copy everything) every time vector.capacity() changes.

So I am left only with that vector will work all the time and if you
can use reserve() it will be as performant as realloc.

>If you use reserve, it will not need to move/copy.

Yes, but often not possible (e.g. when appending elements as they
arrive from an IPC mechanism, or are entered by a user).

Correct me if I am wrong but my understanding of realloc is that it is
most likely to be able to grow in place if there are few allocations
happening e.g. if you are in a loop and the only dynamic memory
allocation that happens is the realloc, it _might_ well be bounded by
unused space and will be able to grow in-place. However, if there are
other mallocs happening between reallocs, these are likely to be
placed right after the realloc buffer and stop it being able to grow
in place.

My point is that in a complex system, you might not be able to use
reserve() correctly but also realloc() is likely not to grow
in-place. In a simpler system where few things happen and realloc has
a good chance to grow-in-place, you might also be able to use
reserve() in a useful way. Obviously there are exceptions.

>Yes, I believe I’ve done that already "Still, the short story is don’t
use malloc/realloc and free unless you find a reason to have to.".
That doesn’t mean that the pros/cons can’t be objectively enumerated
and weighed.

Yes, I understand that you understand. πŸ™‚ I am mostly arguing that
what at first sight might appear like a worthy consideration for using
realloc in C++ is quite possibly not and one should look again πŸ™‚

Yannick

A(Answer):

On Aug 26, 8:07 pm, ytrem…@nyx.nyx.net (Yannick Tremblay) wrote:

There’s a huge difference between hash_map collisions
and failure of realloc to grow in place in the code above:
a hash_map is designed to handle hash collision, a collision
simply result in slightly slower access time. In the sample
code above, realloc deciding that it needs to move everything
elsewhere and memcpy results in a bug! That is not
comparable. Law of average should not be used if it mean
that "most of the time my program will work but once in a
while it will crash" rather than "most of the time my
program will be fast but once in a while it will get a bit
slower".

The code to which you refer is safe for any data which can be safely
and silently relocated. Within those boundaries, use of realloc is
indeed a simple sometimes-fast / sometimes-slow situation.

You can be sure that if it is possible it will realoc in place
but you can’t know "if it is possible". So essentially, you
know nothing and you are sure of nothing.

What kind of FUD argument is this? You know realloc has three
possible outcomes – failure to resize, inplace resize, or some manner
of memcopy/move+resize. This isn’t impractical – one or two C
programmers have actually written reliable systems handling these
branches. I met one once. His name was Bob. He looked very sad.

But my point was this is not even a vaguely credible excuse. It is
simply WRONG. std::vector will do the right thing. It will probably
internally try to grow its buffer and not move it unless necessary.

The old SGI STL provided a hint to the allocator which
could be used for this, but to the best of
my knowledge this is not common practice in current STL
implementations, it’s not available in the GCC headers
shipped with the current Dev-C++ […], and the
Oct ’97 draft Standard section 20.1.5.2 Table 6 makes
it clear that there’s no expectation of any support for
realloc or the SGI-style hint.

Sorry, you are right, my implementation appears to move
the buffer (and copy everything) every time
vector.capacity() changes.

So I am left only with that vector will work all the time
and if you can use reserve() it will be as performant
as realloc.

Two very important considerations, but not the basis for a "never
never never use realloc" recommendation.

If you use reserve, it will not need to move/copy.

Yes, but often not possible (e.g. when appending elements as they
arrive from an IPC mechanism, or are entered by a user).

Correct me if I am wrong but my understanding of realloc
is that it is most likely to be able to grow in place if
there are few allocations happening e.g. if you are in a
loop and the only dynamic memory allocation that happens
is the realloc, it _might_ well be bounded by
unused space and will be able to grow in-place. However,
if there are other mallocs happening between reallocs,
these are likely to be placed right after the realloc
buffer and stop it being able to grow in place.

My point is that in a complex system, you might not be
able to use reserve() correctly but also realloc() is
likely not to grow in-place. In a simpler system where
few things happen and realloc has a good chance to
grow-in-place, you might also be able to use
reserve() in a useful way. Obviously there are
exceptions.

Memory allocation schemes are many and varied, so we can’t draw firm
conclusions. Still, I know it’s not unusual for them to use separate
pools for different sized requests, rather than allowing any small
malloc request coming along to pack right in behind the last request.
I vaguely remember having heard of schemes deliberately scattering or
otherwise targetting allocations to maximise the chance of in-place
realloc.

Doing a very quick Google, I found:
– Paul Hsieh’s "bstrlib.c" assumes 1 in 8 reallocs are in-place
(didn’t find any justification, sounds pessimistic to me but I didn’t
look at the string operation context)
– a similar discussion (with some "big-name" contributors ;-)) at
http://www.cpptalk.net/1-vt23200.htm…er=asc&start=0

Yes, I believe I’ve done that already "Still, the short
story is don’t use malloc/realloc and free unless you
find a reason to have to.".
That doesn’t mean that the pros/cons can’t be
objectively enumerated and weighed.

Yes, I understand that you understand. πŸ™‚ I am mostly
arguing that what at first sight might appear like a
worthy consideration for using realloc in C++ is quite
possibly not and one should look again πŸ™‚

Yannick

Quite so – it’d need to be extreme circumstances before I’d even
consider it seriously….

Cheers,

Tony

LEAVE A COMMENT