Skip to main content
GameDev.net gamedev.net
🔒 Locked

using malloc/free with classes?

Started by Garrland Mar 11, 2003 at 3:26 PM 16 replies 900+ views
Original Post
Garrland
Garrland
Besides the fact that the class''s constructors/destructors will not be called, is there any reason why malloc/free can''t be used to allocate classes? Thanks Journal
Zipster
Zipster
They both get you memory, so I don''t see why not besides what you already said about the constructors and destructors. However I have found that malloc seems to "run out" of memory faster than new, probably because they use different internal buffers to grab memory from.
Qw3r7yU10p!
Qw3r7yU10p!
zipster: which specific implementation are you talking about?
Zipster
Zipster
Whichever implementation comes with MSVC, I didn''t know there were others
Sneftel
Sneftel
Remember that new also sets up the vtable for a class (the compiler adds it to the constructor function, IIRC). So don''t use malloc on a class with any virtual functions.

Basically, you can use malloc with any POD (Plain Old Data) type. A POD is anything that contains only PODs (or is a basic type like int or char*), and has no constructor or destructor or virtual functions declared.


But... but that''s what HITLER would say!!
Garrland
Garrland
Thanks for the info. I didn''t consider the vtable aspect.

Journal
Garrland
Garrland
I think I found my solution to the vtable not getting setup. I discovered that if you override the new operator for a class and call malloc in the overriden function it DOES setup the vtable when it returns.


Fruny
Fruny
quote:
Original post by Garrland
Besides the fact that the class''s constructors/destructors will not be called, is there any reason why malloc/free can''t be used to allocate classes?



Yes, you can.


  
#include <cstdlib>
#include <new>

class MyClass
{
MyClass( int i ) : i_( i ) { }
virtual ~MyClass() {} // yes, you can.


int GetI() const { return i_; }

private:
int i_;
}

int main()
{
// Malloc a chunk of memory

void* memory = malloc( sizeof( MyClass ) );

// Create an object in it

MyClass* obj = new ( memory ) MyClass( 255 );

std::cout << "Equality :" << (obj == memory) << std::endl;
std::cout << "Function :" << obj->GetI() << std::endl;

// Destroy the object (no, we don''t use delete)

obj->~MyClass();

// Release the memory

free( memory );
}



[ Start Here ! | How To Ask Smart Questions | Recommended C++ Books | C++ FAQ Lite | Function Ptrs | CppTips Archive ]
[ Header Files | File Format Docs | LNK2001 | C++ STL Doc | STLPort | Free C++ IDE | Boost C++ Lib | MSVC6 Lib Fixes ]
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan
noVum
noVum
The question is why would you want to use malloc? The only reason I can imagine is that you don''t want to call the constructor
Garrland
Garrland
Well, im working on a memory manager and I want to use Win32''s VirtualAlloc/VirtualFree functions to give me more optimized and controlled way to allocate memory on the windows platform. My Win32MemoryManager class is derived from a pure virtual class MemoryManager. I also have a GeneralMemoryManager that will use standard C malloc/free. I''m also going to use a singlton pattern manage the non-virtual classes.




Journal
niyaw
niyaw
you know that VirtualAlloc rounds up allocation request sizes to the next page boundary, that is, calling it to allocate less than a few dozen kilobytes of memory is really wasteful, right?

it might be a good replacement for malloc when you need megabytes of raw storage for sometime, but i doubt you''ll be better off with allocating small objects with this heavy artillery.

[ms recommends using VirtualAlloc on win9x boxes for requests over 1 mb in size to avoid performance degradation.]
Kosmo
Kosmo
Okay, as far as I have understood the vtables are allocated for each class, not for each instance.
If I have a class and instance of it and use malloc to allocate memory for new instance and then copy the original instance of class to that memory, will it work properly?

I too have a virtual page allocator, but I have also a resource manager, which allocates big chunks every time needed and then gives pieces of that memory to program, so there should be no overhead of virtual page allocation.
Vikke Matikainen
Garrland
Garrland
Yes niyaw, you are correct. The Win32MemoryManager is going to track this inside the class. I'm going to track how much memory is being used per page and not do another VirtualAlloc until the page is exausted. Let say the page size is 4096 returned from GetSystemInfo() and I need to allocate 4 chunks of memory at 1024, 64, 128, and 3000 bytes respectivly. I will not make a second VirtualAlloc call until I ask for the 4th 3000 chunk of memory. Chunks 1-3 will reside in memory allocated by the first VirtualAlloc. VirtualFree will not be called until all the chunks on the page a no longer in use. I also might need some type of process to "defragment" the memory after a long period of many small memory allocation/deallocations. I just hope the overhead doesn't kill my performance. We will see.

[EDIT]Hey, Kosmo has the same idea! [/EDIT]

Journal


[edited by - Garrland on March 13, 2003 3:01:32 PM]
Kosmo
Kosmo
You could try same kind of resource manager solution I have. I have different kinds of resources. First is for permanent resources, like ini-files, loaded to memory, some basic structures and classes, needed through whole program, second is for scene level resources, which are fred after each scene or battle (in my case) and the third one is for temporary resources, which are fred after each frame has passed. This way you have minimum of allocations. I virtual page allocation (about 2MB) takes a lot less time than all those malloc''s and free''s needed every frame.
If you need more thorough explanation, please check the Chriss Hargroves articles "Code on the Cob", in the Game Programming section. This is the place where I got my solution.
And thanks for the Fruny as your example proved most helpfull.

Vikke Matikainen
Zipster
Zipster
quote:
Original post by Anonymous Poster
Zipster, virtualalloc and virtualfree are overkill, the paged memory is slower than if you allocated it in the actual memory new wraps virtualalloc and lets the OS resize the page file, i think you might just be reinventing the wheel...

Um, you talking to me, or did you just type my name for shits and giggles?

LilBudyWizer
LilBudyWizer
It still isn''t clear why you are not using new. You can define your own global new operator as well as new operators specific to a class. You can even use the placement new operator to place a specific instance of a class or any of the fundamental data types for that matter, i.e. int *ptr = new (here) int; which results in ptr=here.

I can understand making a memory manager. I just don''t understand not making it transparent. You are not doing something that was unanticipated. Rather you are doing something that was anticipated and facilities were provided specifically for that purpose. So why not use them?
Keys to success: Ability, ambition and opportunity.
Kosmo
Kosmo
Thnx LilBudyWizer, I did some googling and found very good article about making your memory managing as trasparent as possible:
C++ Memory and Resource Management
Vikke Matikainen

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.