Questions about malloc() in C and C++

rflcptr

Supreme [H]ardness
Joined
Mar 27, 2008
Messages
6,928
Why does this work in C:
Code:
int x = 10;

int * pti = malloc( sizeof(int) * x );
But C++ requires an explicit cast from pointer-to-void:
Code:
int x = 10;

int * pti = (int *) malloc( sizeof(int) * x );

Is the compiler just trying to enforce clarity?
 
The C standard doesn't require an explicit conversion from and to void*, the conversion is done implicitly. I think this is from the C99 standard. C++, however, requires an explicit conversion from void* to another type.
 
Last edited:
The C standard doesn't require an explicit conversion from and to void*, the conversion is done implicitly. I think this is from the C99 standard. C++, however, requires an explicit conversion from void* to another type.

+1, however you should not be using malloc in C++. Use the 'new' operator.
 
To save mikeblas the trouble: why not?

The answer of what you should be using is "it depends"

Not really.

First, you shouldn't mix new/delete malloc/free in the same code base it is a mess and leads to confusion and time wasted when you need to delete/free a point as you need to check how it was created to match the appropriate memory release call. This is universally regarded as a bad idea.

Given the above you should chose one and stick with it.

For C++ it should be new/delete because malloc/free don't call constructors/destructors. If you aren't using contructors/destructors why are you using C++?

Another reason is related to the first question. new() actually returns the proper type. malloc() requires casting. That makes new() typesafe, malloc() is not.
 
Simple types (like integer, in this example) don't have constructors or destructors.

According to your argument, if you're using C++, you're using constructors and destructors. If that's true, the only place you need to worry about matching malloc() with free() is in constructors and destructors of types that contain plain old data types. With proper -- or even only reasonable -- encapsulation, the issue of matching and confusion is rendered moot.

There are benefits to using new and delete, but I disagree that it's a requirement, and certainly don't agree that mixing is universally regarded as a bad idea. Quite the contrary, mixing memory management APIs is often a requirement.
 
Simple types (like integer, in this example) don't have constructors or destructors.

According to your argument, if you're using C++, you're using constructors and destructors. If that's true, the only place you need to worry about matching malloc() with free() is in constructors and destructors of types that contain plain old data types. With proper -- or even only reasonable -- encapsulation, the issue of matching and confusion is rendered moot.

That doesn't even make sense. The reason to use C++ is that you are doing OOP and you will be using new/delete to create/destroy your objects because it will trigger your constructor/destructors. This is the main point of C++. If you aren't using objects then stick with C.

If you are doing OOP in C++ (and by necessity new/delete), then it makes no sense to then use malloc/free, just for the hell of it, for your simple types just because they don't have constructor/destructors. Just because you can doesn't make it the sensible thing to do. It is universally regarded as a poor coding practice. If you actually worked in a team environment this would be made clear in your first code review.

You may be forced to occasionally use free() when calling some ancient C library you are including, but that is a forced necessary evil until the ancient lib is updated, not a pattern to emulate. C++ allows this construct for backward interoperability with old cruft, it isn't for creating new cruft.
 
That doesn't even make sense.
Of course it does. You just didn't understand it.

The reason to use C++ is that you are doing OOP and you will be using new/delete to create/destroy your objects because it will trigger your constructor/destructors. This is the main point of C++. If you aren't using objects then stick with C.
Unless you're advocating wrapping all plain old data types in OO wrappers, then you'll always be allocating simple data types along with your objects, and your argument about having difficulty matching operators still doesn't stand. The practice of using alternate memory managers isn't orthogonal to OOP, and it isn't universally regarded as poor practice. Further, I'm not advocating doing it "just because you can", or "just for the hell of it". I'm simply pointing out that there are reasons to consider the practice.

If you actually worked in a team environment this would be made clear in your first code review.
Why do you expect that making an obviously false assertion about my employment history might substantiate your point?
 
But just make a big array that will hold all your stuff..

int ArrayOf4096IntegerVariables[4096];

Perfect!
 
It was a joke :p

If you are writing your own memory manager in C++, I'm pretty sure you'd be using malloc. I don't know enough to have an opinion or insight on that discussion. I am taking a data structures class next semester, and the first assignment is writing a memory manager that is faster than new/delete in certain scenarios. new/delete from what I know is very safe and generalized to work with any type you might create. But it's not perfect for every scenario, and that's where I think mike was getting at. Situations where you would write your own memory manager to replace new/delete for certain objects/types

With regards to the initial post, I was taught from the beginning to type-cast what malloc returns. It seemed to make sense. I guess it was meant to keep consistent because we were moving from C to C++ the following semester. I didn't realize it wasn't required for C.

I still consider myself a programming nub though, I haven't even been programming for a full year :eek:
 
Of course it does. You just didn't understand it.

Unless you're advocating wrapping all plain old data types in OO wrappers, then you'll always be allocating simple data types along with your objects, and your argument about having difficulty matching operators still doesn't stand. The practice of using alternate memory managers isn't orthogonal to OOP, and it isn't universally regarded as poor practice. Further, I'm not advocating doing it "just because you can", or "just for the hell of it". I'm simply pointing out that there are reasons to consider the practice.

Why do you expect that making an obviously false assertion about my employment history might substantiate your point?

You still haven't given a single reason for using malloc() in C++. Putting malloc/free inside objects isn't a reason. And mixing them for no reason is bad idea.

It is item #3 of Effective C++ by Scott Meyers (Use new/delete and don't mix with malloc/free) If you haven't heard of this, you should get a copy, it is considered one of the essential books for C++ coding:
http://www.amazon.com/Effective-Spe...=sr_1_1?ie=UTF8&s=books&qid=1282445352&sr=8-1

I have been developing C++ for 15 years and the only time I have seen anyone use malloc was C programmers making the transition to C++ and they were corrected in code reviews. There is no reason to use malloc/free in C++ except to interface with old libs.
 
As an Amazon Associate, HardForum may earn from qualifying purchases.
You still haven't given a single reason for using malloc() in C++.
You hadn't asked.

One reason is to avoid exceptions. operator new throws an exception when the allocation can't be satisfied. There are reasons to try and avoid exceptions in code, and there are times when throwing is difficult -- such as in a destructor.

Another reason is alignment. It's difficult to have operator new do any alignment; if you wrote your own operator new(), you'd probably do it by calling malloc() (or another platform-specific allocator) and align the result of that.

A third is code clarity. Since operator new can be overloaded at several different scopes, it can cause confusion -- which version of the operator is actually executing isn't obvious from reading the call site; you have to explore the code, think of its compilation context, and decide what's going on given a wide scope.

There are many other situations to use other allocators, particularly if you look beyond just malloc(). Programs that run for a long time or aggressively handle large amounts of data (or both!) usually end up with custom allocators so that they don't have problems with locking or fragmentation. Because operator new() only ever allocates from one heap, you'll end up writing your own allocator to handle thread-safe, thread- or job-local allocations, lock-free, or multi-heap allocations. Using operator new() to handle specialized allocators, such as a fixed-block allocator or a small-block allocator, is generally a forced fit and usullay more readily expressed with function-oriented allocators -- that is, malloc()-style allocators.

You might find a way to wrap operator new() around different types of memory and their usage scenarios, but you're still using a different allocation scheme at the end of the day. And if you do, then you run the risk of calling the non-obvious operator when you probably wanted your code to be explicitly clear about which allocator you were using.

Your assertion that, if someone is using C++, they should always use operator new and delete is generally correct, but it's not always true. There are advantages to using operator new(), and I think you've noted most of the important ones. But there are very valid reasons to not use it.

Putting malloc/free inside objects isn't a reason.
It wasn't offered as a reason. I explained that the same OOP techniques you mention also bring encapsulation. Encapsulation, when reasonably executed, means that it's not common that the deallocation of an object is too far away from its allocation. Normally, they're encapsulated in the same class and that implementation is hidden from the consumer of the class.

I have been developing C++ for 15 years and the only time I have seen anyone use malloc was C programmers making the transition to C++ and they were corrected in code reviews.
As you gain broader experience, you'll encounter more and more interesting situations and perhaps those will include situations where you want to use a dynamic allocator other than operator new(). Hopefully, it won't be much longer before you realize that broad generalizations aren't really appropriate for engineering--there's always exceptions to rules, and those exceptions aren't as esoteric as you might assume.
 
Your assertion that, if someone is using C++, they should always use operator new and delete is generally correct, but it's not always true. There are advantages to using operator new(), and I think you've noted most of the important ones. But there are very valid reasons to not use it.

First, good reply, when I scanned your first reply at the beginning, I thought you were stating that you would, use malloc for all simple data types inside of classes. Which I thought was nuts, so I thought you didn't have a clue what you were talking about. I stand corrected. If you had started with a reply along these lines I wouldn't have made that assumption. I am aware that there are exceptions, but for just about anyone who has to ask (like the OP), the answer (IMO) is just don't do it. In all but the most esoteric cases it can be avoided.

One reason is to avoid exceptions. operator new throws an exception when the allocation can't be satisfied. There are reasons to try and avoid exceptions in code, and there are times when throwing is difficult -- such as in a destructor.

fooPtr = new (std:nothrow) foo;

Would be my choice over malloc.


Another reason is alignment. It's difficult to have operator new do any alignment; if you wrote your own operator new(), you'd probably do it by calling malloc() (or another platform-specific allocator) and align the result of that.

AFAIK, new can return raw memory just as well as malloc, so there is no advantage to using malloc. Another platform specific allocator perhaps but I don't see the advantage to malloc.

void* operator new (memsize)

A third is code clarity. Since operator new can be overloaded at several different scopes, it can cause confusion -- which version of the operator is actually executing isn't obvious from reading the call site; you have to explore the code, think of its compilation context, and decide what's going on given a wide scope.

Avoid over-riding global new, then you can always call global new. Class over-riding of new is likely the bigger payoff with more specific optimizations possible.
 
If you had started with a reply along these lines I wouldn't have made that assumption.
I did start with such a statement. On the other hand, you made a blanket statement without allowing for any exceptions. That's reveals a certain level of inexperience, based on the expectation that some particular solution is always the right choice. Backed with the repeated assertion that it's "universally regarded as a bad practice", and the insinuation that you club the practice out of members of your team who dare to disagree when their code is up for review, I can't see where you acknowledge the possibility of any alternative.

You followed all that up by personally attacking me, which is as reprehensible as it is counter-productive.

I am aware that there are exceptions, but for just about anyone who has to ask (like the OP), the answer (IMO) is just don't do it. In all but the most esoteric cases it can be avoided.
In my opinion, the best answer is a complete one. Rather than making an over-zealous generalization, a clear answer that explains the issues and lets the questioner decide what they're interested in (or not) without clouding their growing judgment.

fooPtr = new (std:nothrow) foo;

Would be my choice over malloc.
That'll work, if it's available. There are other non-standard alternatives, too.

Now I know why Steam locks up on me all the time...
And why's that?
 
Last edited:
Backed with the repeated assertion that it's "universally regarded as a bad practice", and the insinuation that you club the practice out of members of your team who dare to disagree when their code is up for review, I can't see where you acknowledge the possibility of any alternative.

Perhaps universally wasn't a good choice of words, because clearly not every person on the planet agrees. Would, "generally" regarded as a bad practice it freely mix new/delete, and malloc/free, have met with your approval?

Perhaps next you can put so called "one of the world's foremost experts on C++ ", Scott Meyers, in his place, for his inexperience in making similar admonishments in Effective C++.
Effective C++ Item 3 of 50 said:
Give that malloc and free are ignorant of constructors and destructors, and give that a combination of malloc/free with new/delete can be more volatile than a fraternity rush party, you're just asking for trouble if you do anything but stick to an exclusive diet of news and deletes.

I didn't define out local coding standards, but I agree with them. If someone uses malloc they need justify by showing why they can't achieve the same thing with new. It isn't a case of clubbing out disagreement. It is a case of using best practices unless there is a reason to violate them. We have always found a way to use new instead of malloc.
 
As an Amazon Associate, HardForum may earn from qualifying purchases.
Perhaps universally wasn't a good choice of words, because clearly not every person on the planet agrees. Would, "generally" regarded as a bad practice it freely mix new/delete, and malloc/free, have met with your approval?
Yep, since that makes sense and is appropriate adivce.

Perhaps next you can put so called "one of the world's foremost experts on C++ ", Scott Meyers, in his place, for his inexperience in making similar admonishments in Effective C++.
I expect Scott's book doesn't overstate the problem in the way you did.
 
As an Amazon Associate, HardForum may earn from qualifying purchases.
Yep, since that makes sense and is appropriate adivce.

I expect Scott's book doesn't overstate the problem in the way you did.

Perhaps you missed the quote from his book above.

"you're just asking for trouble if you do anything but stick to an exclusive diet of news and deletes."
 
I saw the quote, but I don't have the context. In my dealings with Scott, he's been pretty reasonable, though I think he over-states some of the points he makes in his book. This might be one of them ... or it might not be.
 
^ What was the context? (I don't have the book, yet)

This context of the quote is that it is the complete final paragraph, that sums up, Item 3 of Effective C++(in my hardcopy version):
Item 3 is titled: Use new and delete instead of malloc and free.

Effective C++ Item 3 of 50 said:
Give that malloc and free are ignorant of constructors and destructors, and give that a combination of malloc/free with new/delete can be more volatile than a fraternity rush party, you're just asking for trouble if you do anything but stick to an exclusive diet of news and deletes.

This isn't taken out of context. It is the whole point. I'd type in the preamble, but it wouldn't change anything, and it would likely go beyond fair use.
 
I can't throw a good example off the top of my head now, but I've experienced instances where a one-size-fits-all (purist?) approach will not work well in every case or that the approach is entirely inappropriate for the domain of input for a problem, even if it theoretically functions. On the other hand, I've written code early on that worked really well for the predicted domain of input for a given program, but simply didn't scale well in other projects. I think these are the extremes of purism and pragmatism, but I did (and still do) have college mentors tugging both ways. As I've been learning more and more, I think software engineering lies somewhere in the middle, depending on the compromise being accommodated. I can see malloc() vs new and free() vs delete being in the same [circumstance] boat.

Either way he rolls, it sounds like a good book to have and learn something from, even if I disagree along the way.
 
Last edited:
This isn't taken out of context. It is the whole point. I'd type in the preamble, but it wouldn't change anything, and it would likely go beyond fair use.
Sounds like his advice is just as bad as yours, then. There are exceptions, and failing to outline them makes people over-cautious. It sounds like that problem has infected your team, from what you've been saying.
 
I can't throw a good example off the top of my head now, but I've experienced instances where a one-size-fits-all (purist?) approach will not work well in every case or that the approach is entirely inappropriate for the domain of input for a problem, even if it theoretically functions. On the other hand, I've written code early on that worked really well for the predicted domain of input for a given program, but simply didn't scale well in other projects. I think these are the extremes of purism and pragmatism, but I did (and still do) have college mentors tugging both ways. As I've been learning more and more, I think software engineering lies somewhere in the middle, depending on the compromise being accommodated. I can see malloc() vs new and free() vs delete being in the same [circumstance] boat.

Either way he rolls, it sounds like a good book to have and learn something from, even if I disagree along the way.

Effective C++ has long considered a must have book for C++ programmers. I would expect nearly every list of recommended C++ books will have it in the top 3. It isn't a programming book, but a series of tips to help you avoid gotchas in C++/write more solid code. The initial grouping of items which includes #3"Use new and delete instead of malloc and free" was aimed specifically at people transitioning from C to C++, which from your initial post sounds like it fits well. I highly recommend it.

I don't consider Meyers advice nor mine to be a purist take. In my case (and I believe in Meyers case as well) it is along the lines of, "if you have to ask the answer is no". Being this isn't a programmer forum, I thought that would be sufficient. My mistake.

new() is intended as the replacement for malloc(). Get good and comfortable with new() before you worry about some exceptional case that you might never see. new() can do everything that malloc() does plus extras (constructors,type safety, exceptions) but all the extras can turned off as well so it works just like malloc() if need be. So new() is the replacement for malloc() does everything it can do and more. It isn't purity to suggest using the intended feature as designed instead of the old C function. Use new() unless you can't.

When can't you use new? When over-riding global new. Global new can't call itself, so in this particular case you will need an alternative memory allocator. Chances are you will never do this in production code.

new() and malloc() mixed throughout your code is a bad idea (like using malloc for your class variables suggested earlier). Consistent code that follow good standard practices unless there is a solid reason, is pragmatic code.
 
Effective C++ has long considered a must have book for C++ programmers. I would expect nearly every list of recommended C++ books will have it in the top 3. It isn't a programming book, but a series of tips to help you avoid gotchas in C++/write more solid code. The initial grouping of items which includes #3"Use new and delete instead of malloc and free" was aimed specifically at people transitioning from C to C++, which from your initial post sounds like it fits well. I highly recommend it.

I don't consider Meyers advice nor mine to be a purist take. In my case (and I believe in Meyers case as well) it is along the lines of, "if you have to ask the answer is no". Being this isn't a programmer forum, I thought that would be sufficient. My mistake.

new() is intended as the replacement for malloc(). Get good and comfortable with new() before you worry about some exceptional case that you might never see. new() can do everything that malloc() does plus extras (constructors,type safety, exceptions) but all the extras can turned off as well so it works just like malloc() if need be. So new() is the replacement for malloc() does everything it can do and more. It isn't purity to suggest using the intended feature as designed instead of the old C function. Use new() unless you can't.

When can't you use new? When over-riding global new. Global new can't call itself, so in this particular case you will need an alternative memory allocator. Chances are you will never do this in production code.
Unless you are porting an app to a fixed-memory platform, or backpatching an existing app that creates connections using new for every connection, such that new now draws from pooled,preallocated resources, or if you're converting something to run on embedded system. I wouldn't say "chances are never" but chances are "very very seldom"

new() and malloc() mixed throughout your code is a bad idea (like using malloc for your class variables suggested earlier). Consistent code that follow good standard practices unless there is a solid reason, is pragmatic code.

What about poor, neglected, new[] and delete[]?
 
Last edited:
I wouldn't say "chances are never" but chances are "very very seldom"
Whether the chances are never, very very seldom, or eventually, it's simply not true that using an allocation operator other than new in C++ is "universally accepted as bad practice", and its usage does most certainly depend on the situation at hand.
 
it's simply not true that using an allocation operator other than new in C++ is "universally accepted as bad practice", and its usage does most certainly depend on the situation at hand.

I have already agreed that was a poor choice of wording. If I could go back in time, I would change it to: "generally" regarded as a bad practice it freely mix new/delete, and malloc/free.

Sounds like his advice is just as bad as yours, then.
:D

I wouldn't say "chances are never" but chances are "very very seldom"

Essentially the same thing. Covered by "chances are".

As a student at this point, chances are he won't even work in C++ after he graduates. Chances are the project he is working on won't be doing this. Chances are that even if it is he won't be the deciding the memory allocation strategy...

It isn't something he need be concerned with anytime soon. He should concentrate on learning the ins and outs of new.
 
Last edited:
Whether the chances are never, very very seldom, or eventually, it's simply not true that using an allocation operator other than new in C++ is "universally accepted as bad practice", and its usage does most certainly depend on the situation at hand.

Agreed, and from personal experience, new(/new[]) and delete(/delete[]) have as many pitfalls as malloc/free, if not more. OP, I think the best advice to glean from all this is learn as many ways as you can, and find which one fits what situation. Use the tool that suits the job
 
You shouldn't be using new or delete. All programmers should universally reserve static memory and invoke placement new to construct objects and not ever worry about deleting them, like this!


Code:
static unsigned char* buffer[sizeof(foo)];
new (buffer) foo;
foo->HelloWorld();


:D
 
Back
Top