1

What parts of standard C++ will call malloc/free rather than new/delete?

This MSDN article lists several cases where malloc/free will be called rather than new/delete: http://msdn.microsoft.com/en-us/library/6ewkz86d.aspx

I'd like to know if this list is (in increasing order of goodness and decreasing order of likelihood):

  1. True for other common implementations
  2. Exhaustive
  3. Guaranteed by some part of the C++ standard

The context is that I'd like to replace global new/delete and am wondering what allocations I'd miss if I did.

Ben Hymers
  • 25,586
  • 16
  • 59
  • 84
  • 1
    In general, I'd avoid malloc/free at all times. Malloc/free will only really work with POD, but if you ever want to replace your POD with something more powerful your going to be in for a rough ride. Malloc/free are really C calls, rather than C++ calls. – IdeaHat Oct 18 '13 at 16:30
  • 3
    @MadScienceDreams Sounds like you have completely missed the OPs question. – πάντα ῥεῖ Oct 18 '13 at 16:38
  • Did you mean to link a different article? Nowhere in the article linked does it state `malloc/free` would be used instead of `new/delete` for code written in C++. Unless you are referring to the table, which is a list of the C Runtime functions that use `malloc/free`. If so, you are interested in the C standard, not the C++ standard. – Zac Howland Oct 18 '13 at 16:38
  • 1
    I guess you mean the list of C library functions in the "remarks" section? Nothing in the C++ library is specified to use `malloc`, although the default `operator new()` is likely to. – Mike Seymour Oct 18 '13 at 16:41
  • Why are you asking for this? Is it just for curiosity, or do you have a particular problem background to solve? – πάντα ῥεῖ Oct 18 '13 at 16:45
  • @g-makulik Mainly I'd like to track allocations with callstack data (to gather statistics and monitor e.g. memory leaks). I also might like to implement a more efficient heap, though this is less important to me. – Ben Hymers Oct 19 '13 at 18:15
  • 1
    @BenHymers Then check the note in my answer. – πάντα ῥεῖ Oct 19 '13 at 18:19
  • @ZacHowland Apologies, I think I trimmed my question down too much; I wanted to say something like "This is the best information I could find easily, it mentions these things which use malloc/free, but I can't find anything similar for C++". – Ben Hymers Oct 19 '13 at 18:29
  • @MikeSeymour Nothing is specified to use `malloc`, but is it also specified *not* to use malloc? Another way of framing what I'm asking for is: when can I can rely on `new` being used and when can't I? – Ben Hymers Oct 19 '13 at 18:32
  • @BenHymers You might be interested to usw a tool like valgrind to get statistcs ob memory allocations, and detection of memory leaks. Don't know if it's available for Windows, but There surely exits s.th. similar. – πάντα ῥεῖ Oct 19 '13 at 18:42
  • @g-makulik I'd like to get more domain-specific statistics though - in this case, I'd like to know things like allocations per frame in a video game, that sort of thing. valgrind is excellent in the general case, though - good recommendation. – Ben Hymers Oct 19 '13 at 18:46

3 Answers3

1

A new is basically a wrapped malloc. The compiler is allowed to use stdio functions at will, for example if you try and implement your own memcpy you'll get some weird recursion. If the compiler sees you copying more than a certain amount (say a dumb bit-for-bit copy constructor) it will use memcpy.

So yes, new is sort of a lie, new means "allocate some memory and construct something there and let me write it as one thing", if you allocate an array of floats say, they are uninitialised, malloc will probably be directly used.

Notice I say probably, I'm not sure if they're set to zero these days :P

Anyway, all compiler optimisations ('cept copy elisioning and other return-value-optimisation stuff - BUT THIS IS THE ONLY EXCEPTION) are invisible to you, that is the point. The program cannot tell it was optimised, you'd have to be timing it and stuff. For example:

(x*10)/2

This will not be optimised if the compiler has no idea about the range of x, because x*10 could overflow, but x*5 might not. So if it optimised it'd change the result.

if(x>0 && x<10) {
    (x*10)/2
} 

will become x*5 because the compiler, being really smart (much more than this) sees "there's no way x*10 can overflow, so x*5 is safe."

If you have a global new/delete that you defined, the compiler cannot optimise because it cannot know it'll have no effects if it does. If you define your own everything it "simplified" to malloc/free will go away.

NOTE:_

I've deliberately ignored the malloc and type-saftey stuff. It's not relevant.

The compiler assumes that malloc, free, memcpy and so forth are all super-optimised and will use them ONLY WHERE SAFE - as described above. There's a GCC thread on the mailing list somewhere where I learned of the memcpy thing.

Alec Teal
  • 5,770
  • 3
  • 23
  • 50
  • new is doing more then malloc (if we ignore the fact people can overload new) – BЈовић Oct 18 '13 at 16:49
  • @BЈовић yes it constructs and such. It is a wrapper around malloc, at some point it will ask the OS for memory. – Alec Teal Oct 18 '13 at 16:53
  • I'm not sure how this answers the question, sorry. "The compiler is allowed to use stdio functions at will" comes close to being a firm "No" on all points, if "stdio" was a typo - did you mean C Standard Library? – Ben Hymers Oct 19 '13 at 18:55
  • @BenHymers absolutely right I meant stdlib. The one where memcpy resides! – Alec Teal Oct 19 '13 at 21:38
  • @BenHymers basically, your question doesn't apply, there are not three levels, the standard states "optimisations may not change the program state", hence the example with multiplication, the compiler cannot have fun unless you do something undefined. Whatever is fastest is what it will probably do. The compiler is VERY clear on exactly what is and isn't undefined. If the compiler can prove something has no side-effects then and only then will it optimise ('cept for constructors, see RVO - ONLY EXCEPTION), if you have your own new that does stuff, the stuff it does is a side effect! – Alec Teal Oct 19 '13 at 21:45
  • @AlecTeal Yep, I'm familiar with what can/can't be optimised already, and I'm aware of the implications of replacing new - what I'm asking is whether replacing new is enough, or if there are other cases where malloc may be being used directly. – Ben Hymers Oct 20 '13 at 11:18
  • @BenHymers no. Of course not. To use malloc directly (rather than via new) is not the C++ way. – Alec Teal Oct 20 '13 at 12:38
  • I think we're on completely different pages here; I'm not asking whether I should use malloc, but whether I can rely on *others* (specifically, parts of the C++ Standard Library) not using it. I already know it'll be used in some cases, I just want to know to what extent. – Ben Hymers Oct 20 '13 at 14:51
  • I've already said I don't think it answers my question, and that we're talking about different things. Let's not get into an infinite loop here :) – Ben Hymers Oct 21 '13 at 08:53
  • @BenHymers I believe your question to stem from a misconception about what new does, and the point of new's existence. Read it again :P – Alec Teal Oct 21 '13 at 16:34
  • Nope, still not getting you. Sorry, but it's probably more likely that you've misunderstood the question rather than I've misunderstood `new` - I hope I know it rather well after all these years. I'm done here. – Ben Hymers Oct 21 '13 at 21:36
1

I'd like to know if this list is (in increasing order of goodness and decreasing order of likelihood):

1. True for other common implementations
2. Exhaustive
3. Guaranteed by some part of the C++ standard

I'd say you cannot really tell from that list (I suppose the one given in the Remarks section) what other C++ implementations than MS will use.

The C++ implementation is free to use any of the OS provided system calls arbitrarily. So the answer for all 3 of your questions is: No.

As for use of malloc() vs new() in implementations of the C++ specific part of the compiler ABI:
I think you can suppose that C++ specific implementations will use new() or placement new for any allocator implementations.
If those listed methods use new() (most unlikely) or malloc() internally to allocate memory doesn't matter for a user of the C++ standard library implementations.

NOTE:
If you're asking from the background of planning to override new(), or use placement new to provide your own memory allocation mechanism for all memory allocation in a programs context: That's not the way to go!
You'll have to provide your own versions of malloc(), free() et. al. then. E.g. when using GCC in conjunction with newlib, there are appropriate stubs you can use for this.

πάντα ῥεῖ
  • 1
  • 13
  • 116
  • 190
  • Thanks! I suspected the answer may just be "No". I'll accept this unless someone steps forward with some guarantees from the standard. – Ben Hymers Oct 19 '13 at 18:49
  • Also, while we're on the subject, do you have any good resources on how to override `malloc` and `free`? As I understood it, the reason to override `new` and `delete` is that it's allowed by the standard, whereas `malloc` and `delete` must be replaced using platform-specific trickery. – Ben Hymers Oct 19 '13 at 18:52
  • @BenHymers Yes this depends on your specific c++ compiler and the OS's ABI. If you're using GCC and newlib the simplest way might be just to provide your own implementations of `malloc()`/`free()` and link them at 1st place before the libs using multiple linker symbols allowed. Ideally you have complete control over your toolchain (i.e. building it yourself). I don't really know about windows (which seems to be your target OS), but MinGW GCC is available. Otherwise specifically for newlib [this link](http://www.embecosm.com/appnotes/ean9/ean9-howto-newlib-1.0.html) might help. – πάντα ῥεῖ Oct 19 '13 at 19:18
  • 1
    @BenHymers Found s.th. that could get you on the track for windows: [Globally override malloc in visual c++](http://stackoverflow.com/questions/1316018/globally-override-malloc-in-visual-c). None of the answers is accepted there, but it seems to contain a viable solution. – πάντα ῥεῖ Oct 19 '13 at 19:28
  • Thanks - that second link does help! It helps demonstrate that it's messy to replace malloc :) I think I'll stick with replacing `new` for now as it's much simpler (e.g. see here: http://oroboro.com/overloading-operator-new/), and seems like it will account for the majority of allocations in my programs. I'll make sure to monitor process memory usage compared to what I gather though, to make sure there isn't too much non-new-allocated memory I'm missing. – Ben Hymers Oct 20 '13 at 11:21
-2

Calloc and malloc are much, much more low level than new and delete. Firstly malloc and calloc are not safe, because u use cast on type whatever you want, and access of data in that memory is uncontrolled. (You can end up writing on someone else's memory) If you are doing some real low level programming you will have to use malloc and calloc. If you are regular programmer just use new and delete they are much easier. Why do you need precise implementation? (I have to say implementation depends because there are many different ones)

Dejan
  • 3,046
  • 3
  • 28
  • 43