Tuesday 13 April 2010

Pointers and Memory Handling In C++

Handling memory resources doesn't need any special knowledge in C++, the memory is freed as soon as the variable is out of scope. Unless you are dealing with pointers. Memory that is addressed by pointer is not freed automatically, even if you are out the scope already. It should be done manually, using delete or some provided special function (If it's some library).

Let's take the following function as an example.

void use_file( const char* fn ){
  FILE* f = fopen( fn, "w" );
  //using f;
  fclose( f );
}

At first sight nothing seems to be wrong here. The memory allocated by fopen is freed at the end of the function with fclose. But what if some exception occurs between those two? Yes, the memory will not be freed. The first attempt to fix this is to add exception handling.

void use_file( const char* fn ){
  FILE* f = fopen( fn, "w" );
  try {
    //using f;
  }
  catch(...){
    fclose( f );
    throw;
  }
  fclose( f );
}

The problem of this solution is that it is too diffusive. Anybody wants to write everywhere try-catch blocks, just to make sure the memory is freed? I am too lazy to do that. There should be a more elegant solution. We can define a class File_ptr, that will behave just like FILE*, but will free resources automatically.

class File_ptr{
  FILE* fp;
public:

  //Constructor that creates File_ptr from FILE*
  File_ptr( FILE* pp ){ fp = pp; }
  
  //Destructor, that closes the file and frees memory
  ~File_ptr(){ if (fp) fclose( fp ) };
  
  //Type conversion operator. It is called every time an object 
  //of File_ptr type needs to be converted to FILE*;
  operator FILE* (){ return fp; }
}

This is a minimum amount of functions that needed for this wrapper class to work. The use_file function then will look like that.

void use_file( const char* fn ){
  File_ptr f = fopen( fn, "w" );
  //using f;
  //file will be closed automatically as soon as f is out of scope
}

But actually it is not all yet. You will also need to define a copy constructor and an assign operator in File_ptr. Here is the good explanation, why.

No comments:

Post a Comment