Click here to Skip to main content
Click here to Skip to main content
 

Local NEW or Automatic heap cleanup when leaving scope

, 30 Sep 2012
Rate this:
Please Sign up or sign in to vote.
Experiment attempting to simplify code, Improve exception and error safety and reduce memory leaks by using Scoped NEW
This is an old version of the currently published article.

Introduction    

Pointers always envied automatic cleanup that is in c++ provided only for big fat slow Static Object or their arrays stored by value. In this article we will introduce concept of scopes also for dynamic objects and scoped version of new/malloc to take advantage of those scopes. Ie associated objects/memory will get destroyed with scope.

new(local) Object();  
Instead of
new Object();  

Why manual cleanup is source of bugs. 

Automatic cleanup provided for static objects saves time lines of code and a lot and I mean really lot of bugs. Bugs by forgetting to match all allocations with deallocations. 
Bugs by memory being leaked when exception or error handler exits something somewhere prematurely and not all control paths contain correct number of release statements. 
Bugs by releasing objects twice or more and corrupting memory by confused condition statements.

Performance point of view   

So we definitely want automatic cleanup that is provided for static objects. But pretty much any program serious about performance will store objects by pointers and not by value because price for reallocation insert or sort is horrendous. 

So can't we have both? Performance and efficiency of pointers and safety and simplicity of static objects by automatic cleanup when leaving scope?

Reinventing Wheel  

Turns out that I am not the first one thinking along those lines and Boost template library already provides us ptr_vector.  vector of shared_ptr or shared_array.
Templates are great when you are not creating library (stl/boost are binary incopatible between versions/compillers) and when you don't mind wrapping every variable to template pretty much rewriting all your code and when everything is working. Take for example this guy having trouble sorting simple array of pointers and geting responses like

"...The IS specifies that a predicate should not assume that the dereferenced iterator yields a non-const object. Arguments should therefore be taken by reference-to-const or by value. 
 

The IS also specifies that algorithms that take function objects as arguments are permitted to copy those function objects. So in most cases, the overloaded function call operator would be a const member function." 

It it unbelivable what complexity we vere able introduce to ehm... "simplify our life"
So if you are like me preffering things small and simple so you know by simple look at source what is going on.
Let's try simpler but I hope equally functional alternative approach writen on 10 lines.  

Scopes for dynamic heap objects ?  

So how automatic cleanup for static objects work? 
It works by adding pointer of every static object within scope to internal invisible static array and when leaving calling destructors for each of them. Can we make something similar for dynamic objects?
Why not. We can have array of void pointers and store pointers to various object types in one single array.
The only issue are calling proper object specific destructors. Unfortunately as far as I know c++ doesnt allow to get destructor adresses. So the only sollution I come up so far is to use virtual destructor in all stored objects so polymorphysm selects proper one for us. 

Implementation of Scope.h 

This one is kept simple with compressed formating just for purpose of article so it is clear what is going on.
Complete implementation of scoped versions of new delete strdup malloc calloc free along with threadsafe
 version of scope called TScope (usefull for using for example global scope from multiple threads etc) is in Scope.h attached zip file along with Example.cpp on top of the article. I didnot attached project files since most of you will not be able to open vs2012 anyway.

struct Scope { // This is Just simple linked list
       struct Obj { virtual ~Obj() {} };
       Scope*    prev;  Obj* ptr;
       Scope() : prev(0) ,   ptr(0) {}	
      ~Scope() { delete ptr; delete prev; } // deleting all childs in reverse order on exit
};

inline void * __cdecl operator new(unsigned int size,Scope& scope)
{
    void *ptr = (void *)malloc(size); // we add all new objects to this linked list
    if(scope.ptr) { Scope* prev=0; prev=(Scope*)calloc(sizeof(Scope),1); *prev=scope;
    scope.prev=prev; }
    scope.ptr=(Scope::Obj*)ptr; 
    return(ptr);
};

This very simple nothrow new overload just as proof of concept;
Also Scope is very primitive linked list kept simple on purpose. 
 
Beware: only objects having virtual destructor work right now for this scoped new. 

Example code 

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include "Scope.h"   

Scope global; // Deallocates/Destroys all associated objects on program exit no matter 
              // what exception or error in program happens

struct A {    // As for objects. They must have virtual destructor
             A(){ printf("\n  A %x",this); }
    virtual ~A(){ printf("\n ~A %x",this); }
};

void Test() {
    Scope local; // all objects associated with scope will be deallocated by leaving procedure
    A* array[3]={0};
    for(int i=0;i<3;i++) {
        array[i]=new(local) A();
    }
    char* text=strdup(global,"this will get deallocated on program exit"); //associate with global scope
    A* a=new(global) A();  // this will get destructor called on progam exit
}

void main() {
    Test();
}                 

Output:

   A 689718   A 68b110   A 68b198   A 68b220 ~A 68b198 ~A 68b110 ~A 689718 ~A 68b220

Points of Interest 

The fact that so far I managed to autodeallocate only objects with virtual destructor kinda sadens me. But I hope that some way to get around this limit is found since deriving from std::string etc just to make it' destructor virtual to allow it's autorelease is kinda unelegant. 

Also if you want to autodeallocate memory from malloc/calloc just create new type of Scope and call free instead of delete in its destructor. 

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Ladislav Nevery
Software Developer (Senior)
Slovakia Slovakia
Past Projects:
[Siemens.sk]Mobile network software: HLR-Inovation for telering.at (Corba)
Medical software: CorRea module for CT scanner
[cauldron.sk]Computer Games:XboxLive/net code for Conan, Knights of the temple II, GeneTroopers, CivilWar, Soldier of fortune II
[www.elveon.com]Computer Games:XboxLive/net code for Elveon game based on Unreal Engine 3
ESET Reasearch.
Looking for job

Comments and Discussions


Discussions posted for the Published version of this article. Posting a message here will take you to the publicly available article in order to continue your conversation in public.
 
QuestionDidn't know there is a new operator in C PinmemberStan Mihai18-Jul-13 4:41 
QuestionWhy not std::unique_ptr<T>? [modified] PinmemberC++ Pirate Programmer18-Oct-12 5:46 
AnswerRe: Why not std::unique_ptr? [modified] PinmemberLadislav Nevery18-Oct-12 16:02 
QuestionThanks PinmemberYannAchard18-Oct-12 1:29 
AnswerRe: Thanks PinmemberLadislav Nevery18-Oct-12 13:00 
GeneralMy vote of 2 PinmemberSeattleC++15-Oct-12 9:53 
GeneralRe: My vote of 2 PinmemberLadislav Nevery16-Oct-12 9:56 
GeneralRe: My vote of 2 PinmemberSeattleC++16-Oct-12 11:24 
GeneralRe: My vote of 2 [modified] PinmemberLadislav Nevery17-Oct-12 5:44 
GeneralRe: My vote of 2 PinmemberSeattleC++17-Oct-12 10:29 
GeneralRe: My vote of 2 [modified] PinmemberLadislav Nevery17-Oct-12 23:06 
QuestionWhat's about an exception handling? Pinmemberkonik1015-Oct-12 6:05 
AnswerRe: What's about an exception handling? [modified] PinmemberLadislav Nevery16-Oct-12 1:47 
GeneralRe: What's about an exception handling? [modified] Pinmemberkonik1023-Oct-12 21:24 
GeneralRe: What's about an exception handling? PinmemberLadislav Nevery24-Oct-12 22:58 
GeneralRe: What's about an exception handling? Pinmemberkonik1025-Oct-12 1:20 
GeneralRe: What's about an exception handling? PinmemberLadislav Nevery25-Oct-12 4:41 
GeneralRe: What's about an exception handling? [modified] Pinmemberkonik1025-Oct-12 5:43 
GeneralRe: What's about an exception handling? PinmemberLadislav Nevery25-Oct-12 12:50 
QuestionException / Thread safety? PinmemberPetro Protsyk8-Oct-12 1:20 
AnswerRe: Exception / Thread safety? PinmemberLadislav Nevery8-Oct-12 7:54 
GeneralMy vote of 2 PinmemberPatrick Niedzielski7-Oct-12 5:38 
GeneralRe: My vote of 2 [modified] PinmemberLadislav Nevery7-Oct-12 10:26 
GeneralRe: My vote of 2 PinmemberPatrick Niedzielski7-Oct-12 10:30 
GeneralMy vote of 5 Pinmembernv33-Oct-12 22:03 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web04 | 2.8.140721.1 | Last Updated 30 Sep 2012
Article Copyright 2012 by Ladislav Nevery
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid