4

Why can't it just be regular function calls? New is essentially:

malloc(sizeof(Foo));
Foo::Foo();

While delete is

Foo:~Foo();
free(...);

So why does new/delete end up having it's own syntax rather than being regular functions?

Sam
  • 7,252
  • 16
  • 46
  • 65
anon
  • 41,035
  • 53
  • 197
  • 293
  • 1
    Can't you override the `new` and `delete` operators so that they *don't* do that (i.e. for singletons)? (I am a novice at C++). – dreamlax Feb 18 '10 at 03:05
  • 2
    The default `new` ends up being more like this: `Foo * pNewFoo = (static_cast(malloc(sizeof(Foo)))->Foo();` Also keep in mind that doesn't take exceptions into account for failed allocations. The `new` syntax looks a lot cleaner to me. – JonM Feb 18 '10 at 03:14
  • 1
    Now that we are at it, it is a little more complex there: `Foo * p = new (malloc(sizeof(Foo)) Foo();`, where the `new (ptr) Type` in the expression is called *placement-new* and is in fact a call to the constructor (user code cannot directly call the constructor) – David Rodríguez - dribeas Feb 18 '10 at 08:47
  • It's not "its own syntax". It's operator syntax. Similar to how you don't have to write +(2, 2), but can write 2+2. Operators in C++ don't use the function call syntax. – jalf Feb 18 '10 at 13:09
  • check Martin York's answer in this link http://stackoverflow.com/questions/240212/what-is-the-difference-between-new-delete-and-malloc-free – Narendra N Feb 18 '10 at 15:05

5 Answers5

7

Here's a stab at it:

The new operator calls the operator new() function. Similarly, the delete operator calls the operator delete() function (and similarly for the array versions).

So why is this? Because the user is allowed to override operator new() but not the new operator (which is a keyword). You override operator new() (and delete) to define your own allocator, however, you are not responsible (or allowed to for that matter) for calling appropriate constructors and destructors. These function are called automatically by the compiler when it sees the new keyword.

Without this dichotomy, a user could override the operator new() function, but the compiler would still have to treat this as a special function and call the appropriate constructor(s) for the object(s) being created.

4

You can overload operator new and operator delete to provide your own allocation semantics. This is useful when you want to bypass the default heap allocator's behavior. For example if you allocate and deallocate a lot of instances of a small, fixed-size object, you may want to use a pool allocator for its memory management.

Having new and delete as explicit operators like other operators makes this flexibility easier to express using C++'s operator overloading mechanism.

For auto objects on the stack, allocation/constructor call and deallocation/destructor calls basically are transparent as you request. :)

ccmonkey
  • 291
  • 1
  • 2
  • This sounds deep; but I do not understand. Can you show some code? – anon Feb 18 '10 at 03:13
  • @anon my C's a little rusty but essentially if you know that you'll ever need 3 of some object at any one time and new/delete will be called frequently. Then you could do this Foo[3] pool; char[3] available = {0, 1, 2}; char top = 2; Foo allocate() { return pool[available[top--]]; } void deallocate(Foo *foo) { available[++top] = foo - pool; } This gives O(1) allocation (provided you adhere to the rules) as opposed to malloc which has to scan free-lists for available space – Robert Davis Feb 18 '10 at 04:09
3

'Cause there is no way to provide complie-time type safety with a function (malloc() returns void*, remember). Additionally, C++ tries to eliminate even a slightest chance of allocated but uninitialized objects floating around. And there are objects out there without a default constructor - for these, how would you feed constructor arguments to a function? A function like this would require too much of a special-case handling; easier to promote it to a language feature. Thus operator new.

Seva Alekseyev
  • 59,826
  • 25
  • 160
  • 281
  • malloc itself is type unsafe; but New can be made type safe by wrapping it as: Foo* new(args) { Foo* ans = (Foo*) malloc(sizeof(Foo)); Foo::init(ans, args); } – anon Feb 18 '10 at 03:15
2

'new/delete' are keywords in the C++ language (like 'for' and 'while'), whereas malloc/calloc are function calls in the standard C library (like 'printf' and 'sleep'). Very different beasts, more than their similar syntax may let on.

The primary difference is that 'new' and 'delete' trigger additional user code - specifically, constructors and destructors. All malloc does is set aside some memory for you to use. When setting aside memory for a simple plain old data (floats or ints, for example), 'new' and 'malloc' behave very similarly. But when you ask for space for a class, the 'new' keyword sets aside memory and then calls a constructor to initialize that class. Big difference.

Jesse K
  • 136
  • 3
1

Why does C++ have separate syntax for greater-than? Why can't it just be a regular function call?

greaterThan(foo, bar);
Anon.
  • 58,739
  • 8
  • 81
  • 86