Skip to main content
gamedev.net
🔒 Locked

new versus *malloc

Started by Omaha 12 replies 950+ views
Original Post
Omaha
Omaha
Does the new operator completely replace the functionality of the malloc family of functions? I''m writing under win32 so it seems to be the flat memory setup would blur the line between using malloc and it''s other brothers like farmalloc, but will new serve all my memory allocation needs? Like if I want to grab a several meg hunk, I know it''s perfectly valid to use new (at least I haven''t had problems with it yet) but it just seems... I dunno, unsettling to do it. Oh well. Just curious.
Amit Rao kt
Amit Rao kt
To get a real idea of the difference new brings you''d have to use object oriented programs which create and destroy objects in runtime,
That would show you how much better new makes life in C++.

Amit Rao (kt)
Technical Associate,
Computer Graphics Department,
NCST,
India
Amit Rao (kt)Technical Associate,Computer Graphics Department,NCST,India
Omaha
Omaha
I''ve done that many many times, and yes, it is very convenient. I''m just asking if the malloc family is obsolete now that new has come to town with easy dynamic memory allocation for all.
Oluseyi
Oluseyi
quote:
Original post by Omaha
...if the malloc family is obsolete now that new has come to town with easy dynamic memory allocation for all.

Bjarne would tell you they were.

I never use malloc in C++. Not that I can''t, just that I prefer new so much. Use whichever is more comfortable for you.

new does have certain advantages, though, such as its ability to throw an exception (unfortunately not the default behavior under MSVC) and your ability to set a special function to call whenever new fails (see _set_new_handler ). You can also overload new and delete (since they''re operators) for your class types.

Eat your heart out, malloc! (sorry, couldn''t resist )
mcfly
mcfly
The New operator is great but if you want to align the memory on a specific boundary you''ll have to take some precautions. If you for example use the [] operator together with New the original offset address will be modified to contain the number of allocated elements and that may trash the aligned memory malloc returned. The point is that even if you overide the new operator with your own memory allocator you can''t rely on that the alignment will be the same after New takes over and constructs the objects. As I should mention, the default new operator in win32 uses malloc so there''s no big difference in functionality between them except for that New automatically calls the constructor for each object plus it has a nicer interface.

/McFly
Mayrel
Mayrel
Something that bugs me about new and friends is that there''s no C++ replacement for realloc -- if I want to resize an array, I''m forced to create a new array and copy the old elements across.

That''s hardly convenient, so I tend to stick with malloc when I''m allocating arrays of primitive types.

Just Plain Wrong
Brother Bob
Brother Bob
Probably the most important thing about new: It calls the object''s constructor, while malloc don''t. And of course, if you use new [], the constructor of each object in the array will be called. Same for delete, it will call the necessary destructors of the object(s).

And if you think you need to resize your array, use std::vector<> instead.
Stoffel
Stoffel
also, new _can_ create memory for an object without calling its ctor (using placement new), so yes, it completely replaces malloc. HOWEVER, there is no replacement for realloc. So no, the family of functions is not replaced. HOWEVER (that''s two now, contradicting myself) I believe realloc was not brought over into C++ memory management because in practice it hardly ever worked, so it caused a hit in efficiency. I''ve never heard the real reason why one way or the other.
Beer Hunter
Beer Hunter
I can only imagine one reason not to have a realloc equivalent in c++, and it''s not a very good reason at all.

If you have a pointer to an item within the dynamically allocated array, and you reallocate that array, the pointer may no longer be valid!

That doesn''t stand up to the fact that people are just going to reallocate the array manually, which would have the same "downside".


In most compilers, new[] calls malloc() anyway. It may not be safe across all compilers, but you can probably get away with using realloc, along with manually calling the contructors / destructors of the elements of the array. But that''s getting a bit awkward, especially considering we already have "vector".
Oluseyi
Oluseyi
I do this in place of realloc:

type *ptr;
// allocate the original array
ptr = new type[num];
// reallocate array:
type *tmp = new type[new_num];
// copy items from ptr to tmp
for(int k = 0; k < ptr_size; ++k)
tmp[k] = ptr[k];
// delete existing array
delete ptr;
// switch pointers
ptr = tmp;

Same difference, I supppose. I''ve never used realloc, and never found a reason to.


Start Here!
Mayrel
Mayrel
quote:
Original post by Oluseyi
I''ve never used realloc, and never found a reason to.


In practice, realloc is likely to use memcpy() rather than copy each byte manually. On Intel architectures at least, memcpy() can be a lot faster than a for loop.

Of course, that doesn''t mean you have to use realloc, because you can just as easily use memcpy() yourself.

Just Plain Wrong
Stoffel
Stoffel
quote:
Original post by Beer Hunter
I can only imagine one reason not to have a realloc equivalent in c++, and it''s not a very good reason at all.


As far as I understand it, here''s the logic for realloc:
1) check through the memory manager to see if there''s enough room after the requested allocation for the new size--potential an expensive operation (?)
2) if there is, update the allocation table
3) if not, allocate new memory size, memcpy, and deallocate old memory.

The reason I thought it was ditched was that step #1 almost always failed, so why fool a user into thinking realloc was faster when the user can just skip to step 3 always and have a faster program?
Boenre
Boenre
If you''re using Win32, why not go all out and use the HeapAlloc() or GlobalAlloc() functions?
Mayrel
Mayrel
quote:
Original post by Stoffel
As far as I understand it, here's the logic for realloc:
1) check through the memory manager to see if there's enough room after the requested allocation for the new size--potential an expensive operation (?)
2) if there is, update the allocation table
3) if not, allocate new memory size, memcpy, and deallocate old memory.

The reason I thought it was ditched was that step #1 almost always failed, so why fool a user into thinking realloc was faster when the user can just skip to step 3 always and have a faster program?



But realloc wasn't ditched: the C++ standard requires implementations to support the C library. In this case, realloc is accessible via #include <cstdlib> .

The issue of whether or not step #1 fails is not a failing with realloc: it is a failing of the particular malloc package and the memory management policy of the programmer -- which may cause fragmentation that is to blame for step #1 failing.

Edit: Step 1 can be very efficient:
  
struct CHUNK {
CHUNK *next;
size_t size;
size_t maxSize;
};
void *realloc (void *ptr, size_t size)
{
CHUNK *chunk = ptr - sizeof(CHUNK);
if (size <= chunk->maxSize) {
// We don't have to move the memory (step 2).

} else {
// We have to move the memory (step 3).

}
}
Step 2 won't be so fast because we'll need to update the free list. We also need to recalculate the maxSize of adjacent chunks when part (or all) of a free chunk is allocated.


Just Plain Wrong


Edited by - Mayrel on November 30, 2001 10:24:00 AM

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.