|
In my Astariel C++ code, I have a setup section where I make calls to initalisation code in about 100 different classes. They run along the lines of: SAFE(D3DBullets.One_Time_Init(), "Main::One Time Init - D3DBullets.One_Time_Init FAILED"); These calls typically reserve and initialise blocks of memory. Like this: // CONSTRUCT THE RESERVOIR Reservoir = (Bullet *)(D3DSage.Malloc(BULLET_RESERVOIR_SIZE * sizeof(Bullet))); Then, in the game closing code, I have a corresponding Cleanup section, again stepping through each of the different classes, this time in reverse order, freeing everything: So D3Dbullets.Cleanup() calls: // DESTROY THE RESERVOIR if(Reservoir) D3DSage.Free(Reservoir,BULLET_RESERVOIR_SIZE * sizeof(Bullet)); This is all very standard and familiar to C++ users. But take a look at Blitzmax code, particularly the example code, and you tend to see a striking absence of cleaup code at app close. So you'd see: Bullet:Tbullet = new Tbullet To reserve a user-defined bullet type object (think c++ class) in the Init section. But at the end of the code you'll most likely see just this: End Huh? What gives? Sometimes, even more confusingly for the C programmer, you'll see: Bullet = Null Shouldn't there be a Delete, or a Release or a Free in there somewhere? This doesn't look right at all! What is actually occurring here (at least so the manual leads me to believe) is that the Blitmax engine keeps a reference count of all reserved memory. As soon as objects in memory are no longer directly referenced, the memory is queued for automatic release. Assigning Bullet = Null is thus 'de-referencing' the memory block, which will in turn let Blitzmax know it needs to be freed. The program End statement automatically de-references and frees all objects. So in practice, you rarely need to worry about freeing up your reserved memory, Blitzmax does it for you. For me, this has been extremely disconcerting. Such has been my C++ training and habits that I feel decidedly uneasy leaving memory management to Blitzmax in this manner. All the examples look (from a C++ perspective) like sloppy code, as there are no cleanup sections. And calls to functions that use local variables to reserve memory, without then freeing that memory, still give me the heebie-jeebies. But in fact such code doesn't normally need a cleanup section. Local function variables are automatically de-referenced when they go out of scope at function close. After a while, you begin to realize how much neater this is. Less cleanup code means less code. And the less code you have to maintain the better. The only issue you really need be concerned about is when using the =Null option to free up an object. You just need to make sure you are not still referencing this object elsewhere in your code, otherwise you will be thinking you have freed an object, when in fact it is still live. Normally in C++ the problem is the other way around. You free an object but then still try to reference it elsewhere, causing all sorts of nasties. So, freaky though it may look at first, the Blitzmax memory management system actually minimizes memory leaks. Which means your code is smaller and your obscure bugs fewer. Which is great! But still freaky…
|