C++ question... malloc or new
Dario ff

I have always been wondering of this while programming. ???

I use C++, but i like using the malloc function for allocating my objects, but i don´t know difference between using new and malloc (differences on runtime process, not writing).

so, my question is, if i use C++, should i always use the new function or i can use malloc as well?

I would really like an answer to this, since I always had this doubt.

Thnx for reading... ;D

bamccaig

AFAIK, malloc just allocates memory. The new keyword allocates memory and initializes the object (i.e. calls the constructor) AKA instantiates an object. It's the difference between having an instance of Foo and having enough memory for an instance of Foo. If you use malloc to create a Foo, then what you really have is a pointer to sizeof(Foo) bytes of garbage, not a Foo. I assume for C++ code you should be using new/delete and for C-only code using malloc/free.

Dario ff

oh ok, but i don´t use too much constructors myself, so i think i will stick with malloc. thnx

Audric
Quote:

if i use C++, should i always use the new function

IMO, when you're using classes, you should always use new and delete.
-> You can't pick the wrong size on allocation,
-> If you later put some code in the constructor and/or destructor, it will be called.

OICW

I'd reccomend using new and delete if you use C++. If you want complete control like with malloc, I remember there's something called allocator class, which should provide you with malloc functionality.

And as far as objects go, you should use new and delete any time.

OnlineCop

I'm in favor of 'new' and 'delete' because of the ability of C++ to overload functions. If your class inherits any others, it's very possible that those other classes could have constructors/destructors.

'malloc' and 'free' have their place for C, but for C++, everyone who has ever discussed this topic with me has strongly opted for 'new' and 'delete'.

Mokkan

You should use new and delete with classes at least. I'm not sure why you'd use malloc over new in any other case either...

EDIT: Wow, I got way beaten.

bamccaig
samo the thief said:

oh ok, but i don´t use too much constructors myself, so i think i will stick with malloc. thnx

Keep in mind that when you say...
Foo* foo = (Foo*)malloc(sizeof(Foo));
The members of the Foo that foo points to are garbage. They can be anything; whatever was in that block of memory before the OS allocated it to your program. This can introduce subtle bugs and/or odd behavior on anything dependent on those values being within some constraint. I haven't done a lot of C coding, but what I have done always had me zeroing newly allocated memory (i.e. memseting the newly allocated memory to 0s).

A constructor goes one step further and sets all members to known default values. Even in C, you can use a constructor concept to initialize a structure, either by wrapping the creation into a function (e.g. create_foo) or by passing the existing pointer into a function (e.g. init_foo) and setting all members to known default values. Either way, you may need to be careful if you're just going to leave it as garbage.

Unless your application requires the finite optimization of not writing unnecessarily to those memory blocks (and in 99.999999999% of cases it won't), I would recommend you either zero the memory or call some kind of initializer/constructor. C++ makes this an easy and intuitive process so why fuck with that? :)

Dario ff

i was talking about malloc because I learned some c way back ago, but now i started using C++, and i got that little doubt. well, suppose I´m going to have a nice day today with replacing some part of my code XD

Kitty Cat
Quote:

The members of the Foo that foo points to are garbage.

Also note that if your class contains other classes (eg. std::string, std::vector), using malloc will NOT initialize those object properly and can crash when you try to use them.

aj5555

there are other alternatives.

Speedo

IMO, it's utterly foolish to write C++ code with malloc/free. If you mix them with new/delete in your code, you risk quite a bit of confusion for yourself or anyone else later on (do I need to free this pointer or delete it? can't interchange the two). If you go entirely malloc/free you're begging for problems initializing C++ objects. And the big question is... what is malloc doing for you that new is incapable of doing?

Onewing
Quote:

there are other alternatives.

Sounds like you're offering to sell him watches in a dark alley...

I personally love new and delete and said goodbye to malloc/free a while ago. The only times I have any difficulty (have to refresh myself) is when I create a multidimensional array with new.

Tobias Dammers

Multidimensional arrays in C are a brain-wrecking piece of crap anyway.
With all the template power C++ bestowes upon us, might as well create a template that encapsulates a plain 1d array (or an array of arrays if you prefer that) into a nice class that behaves like an n-dimensional array. While you're at it, might as well add bounds checking a la std::vector. Only downside is you call a getter method instead of using the [] operator, but that's just syntactic sugar IMO.

Timorg

if your array is of pointers, or they are all positive integers, you could use the [] operator and return -1 or NULL

Tobias Dammers

Yes and no.
Operator[] is supposed to return a reference, and if you're out of bounds, you cannot do this (though throwing an exception would be a proper way of handling this I guess).

axilmar
Quote:

so, my question is, if i use C++, should i always use the new function or i can use malloc as well?

Forget malloc and free, use new.

Don't use delete, use boost::shared_ptr. You might be a newbie, but you will regret it later if you don't do so. It takes a while to learn boost, but it pays off hugely.

Tobias Dammers

I say, manual memory management builds character.

Trezker
#include <boost/shared_ptr.hpp>
typedef boost::shared_ptr<Myclass> MyclassPtr;
MyclassPtr myclassinstance(new Myclass);

Voila, instant garbage collection! ;)

I'm rather dissatisfied with the naming of shared pointer types though.
Now I'm using ClassnamePtr, and ClassnameWeakptr but I don't feel they work well with my coding standard over all. I have Names_with_underscore if there's multiple words, but the shared pointers get CamelCase.

Any tips?

bamccaig

classname_ptr and classname_weakptr? ???:P

Trezker

Maybe you're right...

amber
Quote:

what is malloc doing for you that new is incapable of doing?

realloc?

(I actually don't know. I'd be curious if any people more knowledgable in C++ could weigh in...)

Speedo
Quote:

realloc?

(I actually don't know. I'd be curious if any people more knowledgable in C++ could weigh in...)

It seems to me like the primary use of realloc (at least in C++) would be to resize a dynamic array. Of course, 98% of C++ programmers would then tell you to use vector or another STL container, but even if you insisted on using arrays you could duplicate realloc with a little template magic:

template<typename T>
T* ReAllocate(T* ptr, size_t curElements, size_t newElements)
{
  assert(ptr);
  T* nuptr = new T[newElements];  
  memcpy(nuptr, ptr, sizeof(T) * ((curElements < newElements) ? curElements : newElements));
  delete [] ptr;
  return nuptr;
}

axilmar

The memcpy you do is bad, very bad.

You should never do that with C++ objects. You should always use the assignment operator to copy the data.

Matt Smith
Quote:

If you mix them with new/delete in your code, you risk quite a bit of confusion for yourself or anyone else later on (do I need to free this pointer or delete it? can't interchange the two)

IMO, That's a sound reason for sticking to C. The raison d'etre for C++ is that the OOP model is standard. For this reason alone, you should use new/delete when writing classes.

Speedo
Quote:

You should never do that with C++ objects. You should always use the assignment operator to copy the data.

If we're speaking honestly, you shouldn't be using a function like that to begin with. But if you're going to insist on doing so anyway, you just have to accept the limitations of it.

Karadoc ~~

I thought that last time this topic came up most people were basically saying "use whichever you like, just don't mix malloc/free with new/delete!" Now people seem to be saying "use new/delete, unless you are stupid."

I don't really have an opinion about this, I just find it interesting that the general response has changed (or maybe I just misremembered it).

amber
Quote:

course, 98% of C++ programmers would then tell you to use vector or another STL container

The problem with a vector in this case was that the array needed to shrink as well as grow, and doubling its size every time it needed to grow was not what I had in mind.

I saw no other solution but to hack up something myself using realloc. Of course, it caused one mysterious, frustrating crash (hence why one should use STL when possible :P ), but I fixed that and it's worked fine ever since. ;D

Tobias Dammers
Quote:

The problem with a vector in this case was that the array needed to shrink as well as grow, and doubling its size every time it needed to grow was not what I had in mind.

This is a design decision, not a flaw. Algorithm-wise, it is better to grow exponentially than linearly, in order to maintain a good balance between reallocation calls (which are very costly due to the possible memcpy involved) and memory usage.
Vectors can shrink, too, if you explicitly instruct them to. Read the docs.

axilmar
Quote:

The problem with a vector in this case was that the array needed to shrink as well as grow, and doubling its size every time it needed to grow was not what I had in mind.

std::vector has a functionality to reserve entries so as that reallocation does not happen too often. If you know you can have, let's say, maximum 1000 elements in the vector, you do a vector.reserve(1000), and then adding an element to the vector will not resize it.

Speedo
Quote:

I thought that last time this topic came up most people were basically saying "use whichever you like, just don't mix malloc/free with new/delete!" Now people seem to be saying "use new/delete, unless you are stupid."

Given that you pretty much have to use new for non-builtin types in order to call their constructor, it means that pretty much any use of of malloc/free in C++ is going to have to be mixed with new/delete. Hence why most of us seem to be opposed to it.

SiegeLord
Quote:

Algorithm-wise, it is better to grow exponentially than linearly, in order to maintain a good balance between reallocation calls (which are very costly due to the possible memcpy involved) and memory usage.

I am sure the generic exponential growth might not be optimal for every single situation, which means vector is not optimal everywhere. I'd personally just inherit from vector and alter the associated functions. But it is a flaw. The containers I made myself always had a modifiable growth rate, be it linear or exponential, there's little reason for the option to not be available in std::vector.

OnlineCop

So are we talking about alloc/new, or std::vector in this thread?

1) C++ can use malloc, realloc, etc. However, its drawback is that you don't account very well for default constructors for classes/structs. If you don't use them, there's no good reason NOT to use malloc, except that it's not what the C++ standard is. However, if you've got LOTS of code that would make it too much of a headache to change all your mallocs/frees to news/deletes, then just leave it alone.

2) std::vector has a bunch of nice features. It's also been reviewed by several pairs of eyes, all with different amounts of programming experience behind them, so it's got the benefit of being cross-platform and still very efficient. The decision to double the vector's memory usage each time you exceed its reserve was done because people who know more about memory management, the pipeline, different computer and how their hardware deals with constant memory reallocations, were the ones to sit down and hammer out some good reasoning and have it passed off by whoever sits at the board that decides what gets included into C++'s standard libraries.

For the vectors, I don't always need push_back or assignment between two array. But it's nice if you need them. If you wish to do your own memory management, take a look at cppreference's page on vectors and determine which features you need in your own game.

Personally, I like 'new' and 'delete' over malloc/free, but that's only because I've not used malloc/free as much as I've used new/delete. So it's personal preference, and GNU gcc/gpp both seem to handle "new/delete" in my .C code without complaining whenever I "downgrade" from a C++ project to C.

amber
Quote:

Vectors can shrink, too, if you explicitly instruct them to. Read the docs.

I have, and everything I've read suggests you can reduce size (the current amount of the vector that's in use), but not capacity (the amount of memory allocated for the vector, total). Capacity seems to be left up to the implementation, and the only guarantees made are that you'll have enough space.

Quote:

If you know you can have, let's say, maximum 1000 elements in the vector, you do a vector.reserve(1000)

Not to seem like I'm being difficult (I'm not, this is a legitimate question)-- if you know for sure you're only ever going to have 1000 elements, why not just a 1000-element array?

axilmar
Quote:

Not to seem like I'm being difficult (I'm not, this is a legitimate question)-- if you know for sure you're only ever going to have 1000 elements, why not just a 1000-element array?

You may not be sure that you will have 1000 elements in the end. You may know that the maximum is 1000, but the actual number of elements might not be that.

Thread #597415. Printed from Allegro.cc