Monday, April 30, 2012

How to Add a Simple Memory Leak Test to a C++ Project

The following code illustrates a simple test for memory leaks in C++ programs that allocate memory through the new operator.  The basic trick is to override the new and delete operators and count the number of times each are called; at the completion of your test code, the number of times new is called should equal the number of times delete is called, otherwise, your code is leaking memory.  (This is not a process I invented, but found discussed across the Web.)

You can add this test to your projects using the following 2-step process.

Step 1: Create a file with the following contents and add it to the build.

// How to test for memory leaks in C++ programs
// that allocate memory through the new operator. 
//
// Author: David Turner (of CSUSB)
//


#include <memory>
#include <stdlib.h>


////////////////////////////////////////////////////////////////
//                                                            //
// Override the new and delete operators to keep track of     //
// the number of times they are called.                       //
//                                                            //
// If there is no memory leak, then the number of times new   //
// is called will equal the number of times delete is called  //
// after all destructors run.                                 //
//                                                            //
////////////////////////////////////////////////////////////////


unsigned int newCalls = 0;
unsigned int deleteCalls = 0;




#ifdef _WIN32


    void * operator new(size_t size)
    {
        void * p = malloc(size);
        if (!p) throw "operator new() failed";
        ++newCalls;
        return p;
    }


    void * operator new[](size_t size)
    {
        void * p = malloc(size);
        if (!p) throw "operator new() failed";
        ++newCalls;
        return p;
    }


#else


    void * operator new(size_t size) throw(std::bad_alloc) 
    {
        void * p = malloc(size);
        if (!p) throw std::bad_alloc();
        ++newCalls;
        return p;
    }


    void * operator new[](size_t size) throw(std::bad_alloc) 
    {
        void * p = malloc(size);
        if (!p) throw std::bad_alloc();
        ++newCalls;
        return p;
    }


#endif

void operator delete(void * p) throw()  
{
    if (p != NULL)
    {
        ++deleteCalls;
        free(p);
    }
}


void operator delete[](void * p) throw() 
{
    if (p != NULL)
    {
        ++deleteCalls;
        free(p);
    }
}


Step 2:  Move your test code into a function called test and then use the following for your main function.

int main(int argc, const char * argv[])
{
    extern unsigned int newCalls;
    extern unsigned int deleteCalls;
    
    test();
    assert(newCalls == deleteCalls);
        
    std::cout << "All tests passed." << std::endl;
    return 0;
}

Putting all test code in function test is needed so that objects allocated on the heap have their destructors called.



Thursday, April 26, 2012

How I Started Writing OpenGL Programs in XCode Without Any Knowledge of Objective-C and XCode Interface Builder

This blog post records the Web resources I used to learn how to develop programs that use OpenGL and run under Mac OS X and that don't use GLUT.

I am relatively new to XCode, particularly the Interface Builder system, and I also have no knowledge of Objective-C, although I am very familiar with C/C++.  So my first 2 steps were to learn Objective-C and learn the XCode Interface Builder.  The third step was to learn how to include OpenGL support.


First, I needed to become familiar with Objective-C.  To do this, I read Learn Objective-C, which was good, but left me wondering about some details related to memory management.  To fill in those details, I read Memory Management with Objective C / Cocoa / iPhone, which filled in the missing details for me.

Second, I learned how to create a Cocao application project and use the XCode Interface Builder, which I did by following the XCode Quick Start Guide.

Third, I completed the tutorial Drawing to a Window or View.