C++ don’t use void pointer with new , delete operators


Void pointer can point to any data type but the pointer itself is ignorant of the type which it really points to.In chapter 2 we have discussed the uses of void pointer and how to implement it with other data type.You have also seen that to access the value the void pointer points to you have to cast it to the specific type and any mistake in the type on the part of the programmer can lead to some disastrous result.Here we will see why void pointer should not be used with new operator while allocating dynamic storage.

Link: Void pointer function

When allocating storage dynamically the new operator returns a pointer to the storage.The void pointer can hold the storage address but it is ignorant of the type but nonetheless the use of void pointer with built-in type is safe and sound.Consider the code below.

int *i=new int(90) ;
void *vd=new int(78) ;

delete i ; //Ok memory deleted
delete vd ; //memory deleted

The memory for int(78) is allocated and the void pointer ‘vd’ holds that address and also the storage is deleted safely here so no memory leakage.If you are using code::blocks you will get a warning “deleting ‘void*’ is undefined” this means deleting a void pointer outcome is unknown and the compiler is telling you to be careful here.Although in this case the warning given by the Code::blocks is a bit meaningless because the code work perfectly fine and the storage is deleted but the warning becomes (very)useful in the program such as shown below.

class test
{
private:
  int *storage , size ;
 
public:
  test( int i=0):size(i) {
  cout<< “Constructor ” ;
  storage=new int[size];
  }
 
 ~test() { cout<< “Destructor ” ; delete []storage ; }
};

int main( )
{
void *t=new test(9) ;

delete t ; ///destructor not called

cin.get() ;
return 0 ;
}

If you run the program the constructor is called,so initialization and storage allocation is performed successfully.But when we try to delete the storage the destructor is not called because the pointer does not know the type of object it points to,so the storage pointed by the pointer ‘storage’ is not freed and memory leakage occur here.You will also get a warning here and it is indeed meaningful.

To deal with such error either you give up using void pointer with new operator or you can cast the void pointer to the correct type and call the delete operator.Casting the void pointer makes crystal clear the type of object which it points to resulting in calling the correct destructor.The program below shows that casting the void pointer can prevent from getting any memory leakage.

class test
{
private:
  int *storage , size ;
 
public:
  test( int i=0):size(i) {
  cout<*lt; “Constructor ” ;
  storage=new int[size];
  }
 
 ~test( ) { cout<< “Destructor ” ; delete []storage ; }
};

int main( )
{
void *t=new test(9) ;

void *st=new string(“happy”) ;
delete st ; ///Memory deleted
///or delete (static_cast<string *>(st)) ; ///works fine

delete (static_cast<test *>(t)) ; ///memory deleted

cin.get() ;
return 0 ;
}

If we cast the pointer to the appropriate type the destructor is called and the memory is freed also the compiler doesn’t give any warning,so every one is happy-the compiler,the programmer,the void pointer and the delete operator.But there can be a glitch here,if you cast the void pointer to some other type,say in the above program if you cast the pointer ‘t’ to any type other then the ‘test’ type the destructor would not be called.

delete (static_cast<string *>(t)) ; ///destructor not called,memory leakage

Since the destructor is not called there is a memory leakage and also note this time the compiler(in Code::Blocks) doesn’t give any warning.





Conclusion

Using void pointer for dynamic allocation is dangerous and also if you intend to cast it while using it there is still a risk of unintentionally casting it to inappropriate type.Either way you have a risk to take,so the best way to avoid all these unnecessary risks is to not assigned the dynamic memory address to the void pointer until there is some sure way to cast back the void pointer to the correct type.


Related Link

 
->Dynamically allocating memory in C++ with new and delete operators.
 
->New,delete operators and class object.
 
->Best way to overload new and delete operators in C++.