operator delete (Función)

La memoria que se asigna dinámicamente mediante el operador new se puede liberar con el operador delete. El operador delete llama a la función operator delete, que libera la memoria para que la use el grupo disponible. El uso del operador delete también inicia una llamada al destructor de clase (si hay alguno).

Hay funciones operator delete globales y de ámbito de clase. Solo se puede definir una función operator delete para una clase dada; si se define, oculta la función operator delete global. La función operator delete global siempre se llama para las matrices de cualquier tipo.

La función operator delete global, si se declara, toma un único argumento de tipo void *, que contiene un puntero al objeto que se va a desasignar. El tipo de valor devuelto es void (operator delete no puede devolver un valor). Hay dos formas para las funciones operator delete de miembro de clase:

void operator delete( void * );
void operator delete( void *, size_t );

Solo una de las dos formas anteriores puede estar presente para una clase dada. La primera forma funciona según el funcionamiento descrito para operator deleteglobal. La segunda forma toma dos argumentos: el primero es un puntero al bloque de memoria que se va a desasignar y el segundo es el número de bytes que se van a desasignar. La segunda forma es especialmente útil cuando se usa una función operator delete de una clase base para eliminar un objeto de una clase derivada.

La función operator delete es estática; por consiguiente, no puede ser virtual. La función operator delete obedece al control de acceso, tal como se describe en Control de acceso a miembros.

En el ejemplo siguiente se muestran las funciones definidas por el usuario operator new y operator delete diseñadas para registrar asignaciones y desasignaciones de memoria:

Ejemplo

// spec1_the_operator_delete_function1.cpp
// compile with: /EHsc
// arguments: 3
#include <iostream>
using namespace std;

int fLogMemory = 0;      // Perform logging (0=no; nonzero=yes)?
int cBlocksAllocated = 0;  // Count of blocks allocated.

// User-defined operator new.
void *operator new( size_t stAllocateBlock ) {
   static int fInOpNew = 0;   // Guard flag.

   if ( fLogMemory && !fInOpNew ) {
      fInOpNew = 1;
      clog << "Memory block " << ++cBlocksAllocated
          << " allocated for " << stAllocateBlock
          << " bytes\n";
      fInOpNew = 0;
   }
   return malloc( stAllocateBlock );
}

// User-defined operator delete.
void operator delete( void *pvMem ) {
   static int fInOpDelete = 0;   // Guard flag.
   if ( fLogMemory && !fInOpDelete ) {
      fInOpDelete = 1;
      clog << "Memory block " << cBlocksAllocated--
          << " deallocated\n";
      fInOpDelete = 0;
   }

   free( pvMem );
}

int main( int argc, char *argv[] ) {
   fLogMemory = 1;   // Turn logging on
   if( argc > 1 )
      for( int i = 0; i < atoi( argv[1] ); ++i ) {
         char *pMem = new char[10];
         delete[] pMem;
      }
   fLogMemory = 0;  // Turn logging off.
   return cBlocksAllocated;
}

A partir de Visual C++ 5.0, el compilador admite los operadores new y delete de matriz de miembros en una declaración de clase. Por ejemplo:

// spec1_the_operator_delete_function2.cpp
// compile with: /c
class X  {
public:
   void * operator new[] (size_t) {
      return 0;
   }
   void operator delete[] (void*) {}
};

void f() {
   X *pX = new X[5];
   delete [] pX;
}

Comment

El código anterior se puede utilizar para detectar "pérdidas de memoria", es decir, la memoria que se asigna en el almacén libre pero que nunca se libera. Para realizar esta detección, se vuelven a definir los operadores new y delete para determinar la asignación y desasignación de memoria.

Vea también

Referencia

operador new (Función)

new (Operador) (C++)

delete (Operador) (C++)