Code Red > ARX Programming

Smart Pointers

(1/2) > >>

Chuck Gabriel:
I have been asked to give an explanation of what smart pointers are and why you might want to use them in your ObjectARX programs.  Here goes.

To understand why there is a need for such a thing as a smart pointer, it is important to first understand some basic facts about memory management in C++.  When you allocate memory for a variable in C++, you can take that memory from either the stack or the heap.  Variables placed on the stack are sometimes called automatic variables, because when they go out of scope (I sure hope everyone knows what that means) the memory they used is returned to the stack automatically.  Variables placed on the heap are called dynamic variables, because the size and location of the memory they use can change over their lifetimes.  Dynamically allocated variables have to be told explicitly to release the memory allocated to them.  Dynamically allocated variables will always be pointers.  If you don't know what a pointer is, that is a topic for another discussion altogether.

Consider this block of code:


--- Code: ---void test() {
  int x = 0; // automatic variable
  int* pY = new int(1); // dynamic variable
  delete pY; // pY deallocated here
} // all variables in the preceeding block go out of scope here.

--- End code ---

The memory for x gets release at the closing brace of the function.  However, if I had neglected to release the memory for pY (via delete), I would have a memory leak, and since pY had gone out of scope I would have no way of correcting my mistake.

This is where smart pointers come in.  Smart pointers wrap a dynamically allocated variable in a class that manages the allocation and deallocation of memory automatically.  Here is an example:


--- Code: ---class AcDbDatabasePointer {
  AcDbDatabase* pDb; // The wrapped pointer
public:
  AcDbDatabasePointer(bool buildDefaultDrawing = true,
                                bool noDocument = false) :
  pDb(new AcDbDatabase(buildDefaultDrawing, noDocument)) {} // memory gets allocated in the constructor
  ~AcDbDatabasePointer() {
    if(pDb) delete pDb; // and deallocated in the destructor
  }
  AcDbDatabase* operator->() {
    return pDb; // forward member function and variable calls to the wrapped object
  }
  AcDbDatabase* object() {
    return pDb;
  }
  void close() {
    if(pDb) delete pDb;
    pDb = 0;
  }
};

--- End code ---

Here is how you would use that in application code:


--- Code: ---void test() {
  AcDbDatabasePointer db;
  // do something with the database.  maybe draw a nice smiley
}  // db goes out of scope here.  It's destructor gets called automatically, which takes care of deallocating the memory used by the wrapped pointer.

--- End code ---

Clear as mud?

The ObjectARX API provides several different types of smart pointers right out of the box.  Probably the most commonly used smart pointer in ObjectARX would be the AcDbObjectPointer template class.  Smart pointer classes frequently are template classes for reasons that will become apparent once you begin to explore them for yourself.  There are also smart pointer classes for symbol tables, symbol table records and probably some other things I'm not aware of.

The choice to use them or not is yours, but I think you will find that they dramatically decrease the opportunity for memory management errors in your code, and they frequently make your code more compact and concise.

LE:
Perfect.

Swift:
Nice post Chuck!

Draftek:
Thanks a bunch, Chuck.

Chuck Gabriel:
Thanks for the feedback guys.  It's nice to know I'm not the only one interested in this stuff.

Navigation

[0] Message Index

[#] Next page

Go to full version