views:

510

answers:

6

My question specifically is in regards to arrays, not objects.

There a few questions on SO about malloc()/free() versus new/delete, but all of them focus on the differences in how they are used. I understand how they are used, but I don't understand what underlying differences cause the differences in usage.

I often hear C programmers say that malloc() and 'free() are costly operations, but I've never heard a C++ programmer say this about new and delete. I've also noticed that C++ doesn't have an operation that corresponds to C's realloc()`.

If I were writing an equivalent to C++'s vector class, I would want to avoid copying the entire array when resizing it, but with new and delete you have to copy. In C, I would simply realloc(). It's worth noting that realloc() might just copy the entire array, but my impression was that it used the same pointer and allocated less space for it, at least when sizing down.

So my question is, how do the algorithms used by malloc() and free() differ from those used by new and delete. More specifically, why does the C way have a stigma of being more expensive, and why doesn't the C++ way allow resizing without copying?

+5  A: 

There's no real difference under the hood - usually the default new and delete operators will simply call through to malloc and free.

As for "the stigma of being more expensive", my theory is this: back in the day, every cycle counted, and the time taken by malloc really was significant in many situations. But by the time C++ came along, hardware was much faster and the time taken by the free store manager was proportionally less significant. The emphasis was shifting from efficient use of machine resources to efficient use of programmer resources.

Why C++ lacks a realloc equivalent, I don't know.

RichieHindle
because realloc, a lot of the time, simply allocs a new block, copies the old data to the new block and then frees the original block.If you want a dynamically re-sizable array use std::vector
Goz
Back in the day? Well, look at the code for malloc and you'll see why it can be costly even today. Why do you think there is so much research into efficient garbage collection? If anything, it's worse today, because there are so many alloc/free's in code, without much regard for the cost.
xcramps
@xcramps: What I'm saying is that it's an issue of perception, rather than a tangible technical difference.
RichieHindle
Yes, even today frequesnt reallocations can make the application much slower. That's why there's vector::reserve().
sharptooth
@Goz: Yes, but someone has to *write* `std::vector`, in C++. Why is that person denied a `realloc` equivalent?
RichieHindle
there weren't denied :) there is placement new/delete.
moogs
A: 

they fundamentally use the same techniques for allocation - certainly, on most implementations, the default C++ runtime new will not be much faster than malloc. One of the big difference is that you can rewrite allocator in C++ so that you can use allocators optimized to your expected memory behavior - you can do that in C as well of course, but it is a bit more cumbersome syntax-wise.

David Cournapeau
+1  A: 

"new and delete can be costly operations" - there, you have now heard a C++ programmer say it. But seriously, dynamic memory allocation costs the same in both languages.

anon
well actually it "can" cost more to do a new because the constructor gets called for each item ...
Goz
@Goz. The constructors for primitive types do nothing and any decent compiler will happily optimize them out.
sharptooth
hence why i put can in inverted commas ...
Goz
+1  A: 

i dunno about the C "stigma", but for resizing C++. you can use placement new to customize the behavior of new.

But why do it? Let the compiler makers do what they do best!

moogs
Do you have any links for how one would go about doing this?
Imagist
@Imagist: http://en.wikipedia.org/wiki/Placement_syntax
RichieHindle
+2  A: 

Often new and delete use malloc() and free() for memory allocation/deallocation. Anyway they must use some primitives for memory allocation/deallocation - with overloading new and delete operators that could be something faster that malloc() and free() (say it can be functions working on a memory pool for fixed-size objects). Usually unless you've actually done such overloading you will not see any difference in costs of memory allocation done each of these ways.

Reallocation is not allowed simply because not all datatypes allow moving in memory - they need copy constructors and destructors invoked to be moved properly. For example you might have some graph node structures stored in an array. If you move them blindly the pointers pointing between objects will become invalid.

sharptooth
+1  A: 

To thoroughly generalise, C has traditionally been used in much more resource restricted environments, both because its been around longer and because it is used in embedded applications. The potential computational cost of malloc is therefore a worry, whereas C++ which is more commonly used on PCs doesn't worry so much.

new and delete may well be implemented by your compiler in a very similar way to malloc, but they have one difference (and this is why they exist) - they call the constructor and destructor for the relevant item.

When I say constructor, I do of course mean any initialisation required (filling out VTABLES, setting the initialisers etc.). This can potentially make new and delete slower, but in a side by side comparison (allocation and freeing an int for example) there is no fundamental difference.

WillW