-3

I have written a simple function as following:

void *operator new(size_t size) throw(std::bad_alloc)
{
    void *p;
    p =  malloc(size);
    if(!p)
       throw bad_alloc();
    return p;
}

What else can i do to improve this? Would malloc be more effective than new? If I want to write new[] do I only need to change just the function signature?

user103214
  • 3,478
  • 6
  • 26
  • 37
  • I don't understand your question about `malloc`. – Kerrek SB Nov 17 '11 at 22:55
  • 6
    Why are you even overriding `operator new`? This is very special-purpose tool, if you have that basic questions, then it's not meant for you. – Cat Plus Plus Nov 17 '11 at 22:56
  • @KerrekSB: It seems i'm only using malloc as replacement for default new, so whats the point of overloading? – user103214 Nov 17 '11 at 22:58
  • 2
    @user974191 - Exactly -- what is your point in overloading new? What are you trying to achieve? – Robᵩ Nov 17 '11 at 22:59
  • 1
    @CatPlusPlus: Please enlighten me about the special-purposes. So i can stop using it. I don't know why i'm doing this. – user103214 Nov 17 '11 at 23:00
  • @user974191, `new` automatically calls constructors. By replacing it with `malloc` you are putting a time-bomb in your applications ready to blow up on you when you least expect it. – Shahbaz Nov 17 '11 at 23:02
  • 1
    @user974191: You got it the wrong way round. `::operator new()` **is** always implemented in terms of `malloc()`. Perhaps you are confused about the difference between `::operator new()` and the C++ `new` **expression**? – Kerrek SB Nov 17 '11 at 23:02
  • We should have a FAQ on the purpose of overloading `operator new`. I think there is a valid question here. – pmr Nov 17 '11 at 23:04
  • I'm only trying to learn why or when should i overload new operator. But It seems no real purpose of overloading new as i'm only using `malloc` instead of `new` in my code. – user103214 Nov 17 '11 at 23:07
  • In the code above you don't overload operator new, you replace it. Overloading it would mean adding another version with placement-new syntax. Such an overload can make sense if you need an object to be allocated in special places (like shared memory); indeed the standard placement new is such a case (where the special place is just where the supplied pointer points to). On the other hand, there are extremely few cases where you want to replace the global `operator new`/`operator delete`. One case which comes to mind would be if you implement a garbage collector. – celtschk Nov 17 '11 at 23:18
  • @user974191: Don't use `malloc` in client C++ code. It won't behave properly. As for overriding `operator new`, you don't need to do it, and won't need to do it for a long time. – Cat Plus Plus Nov 17 '11 at 23:26
  • 1
    For me it looks like you're trying to "create" the new operator like if it wasn't defined at all in C++. Just in case, you don't need to overload it to use it. – Dalmas Nov 17 '11 at 23:27
  • Am I replacing the new operator or am i overriding the new operator? – user103214 Nov 17 '11 at 23:36
  • @KerrekSB: The C++ standard ensures that `::operator new` *can* be implemented in terms of `malloc`, but it's certainly not required. At one time it was extremely common, but it seems like I looked at some a few a couple of years ago, and it didn't seem to be all that common any more (but I *could* be remembering something else). – Jerry Coffin Nov 18 '11 at 05:14
  • @JerryCoffin: I think [we discussed this recently](http://stackoverflow.com/questions/7443782/does-dynamic-memory-allocation-differ-in-c-and-c-in-popular-implementations) and concluded that the standard actually *suggests* `malloc()`. But of course it's not *prescribed*, granted. An oversimplification on my part because I think the OP is confused about something else. – Kerrek SB Nov 18 '11 at 12:35
  • @KerrekSB: I don't think the standard particularly suggests using `malloc`. The closest I can see is footnote 32: "The intent is to have operator new() implementable by calling malloc() or calloc(), so the rules are substantially the same. C++ differs from C in requiring a zero request to return a non-null pointer." I'd personally call that closer to a "grudging admission" than a "suggestion", though in the end it doesn't matter a lot. – Jerry Coffin Nov 18 '11 at 15:32

3 Answers3

1

This code will work the way it is, but if you do this, you pretty much need to write a matching ::operator delete that will work with it:

void operator delete(void *block) throw() {
    ::free(block);
}

Personally, I'd probably modify your code to something more like:

void *operator new(size_t size) throw(std::bad_alloc)
{
    void *p =  malloc(size);
    if(!p)
       throw bad_alloc();
    return p;
}

I prefer to initialize everything I can, rather than create an uninitialized variable, and only later assign a value to it. In this case, the difference is pretty minor, but I consider it a habit worth cultivating.

As far as being more effective than the default implementation of operator new, I'd say chances are that no, it won't be more effective, and might well be less effective. What you've provided is basically how many standard libraries were implemented toward the dawn of C++, but since then, many (most?) have done more work on their implementation of ::operator new to tailor it more closely to how dynamically allocated memory tends to be used in C++ (where malloc is mostly oriented toward how it's used in C, which is typically at least a little different).

As far as new[] goes, yes, it's just a change of function signature. Despite being used for single vs. multiple allocations, the requirements on operator new and operator new[]` are identical.

Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
0

If you replace global operator new you also should replace the nothrow variant. And, of course, global operator delete (both the normal and nothrow variant, because if the constructor of the object throws, the nothrow variant of operator delete is called for nothrow operator new).

I guess in most implementations the built-in operator new looks more or less exactly like your replacement. Anyway, in general I'd not expect that you can beat the internal implementation of operator new.

celtschk
  • 19,311
  • 3
  • 39
  • 64
0

operator new is responsible for allocating the underlying memory of an object. Some applications use other allocation schemes than malloc to allocate memory. One example is pool allocation: The application requests a large amount of memory from the operating system and manages how that memory itself. This can safe the overhead of a system call, prevent fragmentation or provide time guarantees for memory allocation that the operating system usually wont.

If you don't know if this could improve the performance of your program, it probably does not matter for you.

pmr
  • 58,701
  • 10
  • 113
  • 156