• Advertisement
Sign in to follow this  

Constructor call with malloc?

This topic is 4724 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I've been debugging my engine off and on all night when I made an odd observation: when you malloc something, the constructor is never called! For example:
//creates a new instance of Octtree and calls the default constructor
Octtree *tree = new Octtree() 

//Allocates memory for an Octtree but no constructor call
Octtree *tree = (Octtree *) malloc(sizeof(Octtree))

//Allocates memory and sets all pointers to null, but still doesn't call default constructor
Octtree *tree = (Octtree *) malloc(sizeof(Octtree))
ZeroMemory(tree, sizeof(Octtree))

Seeing as I'm a die-hard C programmer and shudder to think of anyone but me messing around with my memory allocation, is there any way to call the default/any constructor after mallocing? Or is it necessary to use the new keyword?

Share this post


Link to post
Share on other sites
Advertisement
That's right. malloc() never calls the constructor, it just allocates raw chunks of memory. To call the constructor, you need to use new or malloc and placement new.

Share this post


Link to post
Share on other sites
Might I recommend merely using new, rather than a malloc()/placement new combination? Because new isn't managing memory any more significantly than malloc() is, unless you think that an automatic call to the constructor is an evil thing to perform without your consent. (Have fun dealing with uglier code, though; I hope I never have to mess with it. [wink])

Share this post


Link to post
Share on other sites
new is just malloc with a constructor call. I believe that it also sets up the vtables and whatnot for all your polymorphic needs. I see no reason to not use it other than a desire for pain coupled with a fear of change. =)

-me

Share this post


Link to post
Share on other sites
I think this is a pretty bad idea, but here's an example of how you could do it.


#include <iostream>
#include <string>
#include <new>
#include <cstdlib>

int main()
{
using namespace std;

// Get some memory with malloc.
void *memory = malloc(sizeof(string));

// If we didn't get the memory, then it's really time that you upgraded.
if(!memory) return -1;

// Create a string object in that memory.
string *string_pointer = new(memory) string("Hello World!");

// Use that string object for something.
cout << *string_pointer << endl;

// Call its destructor.
string_pointer->~string();

// Free the memory.
free(memory);


cin.get();
return 0;
}





While we're on the subject, always release your memory with whatever you used to get it, i.e.:

malloc/realloc/calloc --> free
new --> delete
new [] --> delete []
operator new --> operator delete


If you match up the wrong ones your computer will implode and create a minature black hole that will swallow you! Don't fool around with these things!

Share this post


Link to post
Share on other sites
Well seeing as you dont trust the compiler to allocate memory for you with its new operator, and you have to use new of some kind to construct the allocated object, Why dont you make your own new. The awsome thing about C++ is that(among other things) you can overload most operators. I would suggest reading up on the operator new and operator delete functions and their array equivelents because they give you all the controll you want. These operators can be defined at the global level and they can be static functions for a class if that class should be allocated differently.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Quote:
Original post by Yohumbus
Well seeing as you dont trust the compiler to allocate memory for you with its new operator, and you have to use new of some kind to construct the allocated object, Why dont you make your own new. The awsome thing about C++ is that(among other things) you can overload most operators. I would suggest reading up on the operator new and operator delete functions and their array equivelents because they give you all the controll you want. These operators can be defined at the global level and they can be static functions for a class if that class should be allocated differently.


Yes, until someone is going to work on your code, who doesn't expect this. And if he does, and he already assumes the default C++ habit, he'll have a very hard time maintaining your code. IMHO it's better to refrain from overloading the new / delete operators, and if you have to, please do it for specific cases.

For the rest I totally agree with Oluseyi.

Share this post


Link to post
Share on other sites
Quote:
Original post by skyfire360
Seeing as I'm a die-hard C programmer...

Seeing as you are a die-hard C programmer, you shouldn't be using constructors in the first place.

Share this post


Link to post
Share on other sites
Usually if people are doing this (zeroing memory) I assume it is because they are just avoiding writing constructors which initialise values to zero.

This is just plain lazy and when you get into using virtual functions or member data which isn't builtin types, it will cause you big problems.

Let C++ do what it's supposed to do. Its type system brings all kinds of benefits. Don't try and subvert it.

Trust the compiler, but look at the generated code if you have any doubts.

If there's something special you need to do such as using a memory pool to speed things up then look at using a library such as boost or Loki to look after it for you. I simply added Loki's small object allocator (you derive from it) and it vastly improved the performance of my application.

Share this post


Link to post
Share on other sites
AP, I dont meen for him to change the behavior of new and delete to something other than allocating memory. If he wants to ensure that malloc is used when new is used all he has to do is overload new and delete to allocate with malloc even though that's what the default behavoir should already be. There are no maintenence costs with overloading new and delete, that's why they exist and the best way to get with the language would be to use its more powerfull features (operator overloading and the like) to make his code easier to use.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement