C ++: El principio de realización de nuevo y eliminar


Operador nuevo y funciones de eliminación de operador

Nuevo y eliminar son operadores para la aplicación de memoria dinámica y la liberación por parte del usuario , el operador nuevo y el operador eliminar son funciones globales proporcionadas por el sistema , el operador de nuevas llamadas nueva función global en la parte inferior para solicitar espacio, y eliminar utiliza el operador eliminar la función global en la parte inferior para liberar espacio .

/*
operator new:该函数实际通过malloc来申请空间,当malloc申请空间成功时直接返回;申请空间失败,尝试执行空间不足应对措施,如果改应对措施用户设置了,则继续申请,否则抛异常。
*/
void* __CRTDECL operator new(size_t size) _THROW1(_STD bad_alloc)
{
    // try to allocate size bytes
    void* p;
    while ((p = malloc(size)) == 0)
        if (_callnewh(size) == 0)
        {
            // report no memory
            // 如果申请内存失败了,这里会抛出bad_alloc 类型异常 
            static const std::bad_alloc nomem; 
            _RAISE(nomem);
        }
        
    return (p);
}

/*
operator delete: 该函数最终是通过free来释放空间的 
*/
void operator delete(void* pUserData)
{
    _CrtMemBlockHeader* pHead;
    
    RTCCALLBACK(_RTC_Free_hook, (pUserData, 0));
    if (pUserData == NULL)
        return;
    _mlock(_HEAP_LOCK);  /* block other threads */
    __TRY
    
        /* get a pointer to memory block header */
        pHead = pHdr(pUserData);
        
    	/* verify block type */
    	_ASSERTE(_BLOCK_TYPE_IS_VALID(pHead->nBlockUse));
    	
    	_free_dbg(pUserData, pHead->nBlockUse);
    	
    __FINALLY
        _munlock(_HEAP_LOCK);  /* release other threads */
    __END_TRY_FINALLY
    
    return;
}

/*
free的实现
*/

#define free(p) _free_dbg(p, _NORMAL_BLOCK)

A través de la implementación de las dos funciones globales anteriores, se sabe que el operador nuevo realmente está solicitando espacio a través de malloc . Si malloc solicita el espacio con éxito, volverá directamente. De lo contrario, se ejecutarán las contramedidas proporcionadas por el usuario para proporcionar espacio insuficiente. Si el usuario proporciona esta medida, continúe aplicando, de lo contrario Lanza una excepción. La eliminación del operador finalmente libera espacio de forma gratuita.

Tipo incorporado

Si está solicitando un tipo de espacio incorporado, new y malloc, delete y free son básicamente similares, la diferencia es: new / delete solicita y libera un solo elemento de espacio, new [] y delete [] solicitan espacio continuo, Y new lanzará una excepción cuando no pueda solicitar espacio, y malloc devolverá NULL.

Tipo personalizado

  • El principio de nuevo

    1. Llame al operador nueva función para solicitar espacio

    2. Ejecute el constructor en el espacio solicitado para completar la construcción del objeto.

  • El principio de borrar

    1. Ejecutar destructores en el espacio para completar la limpieza de recursos en objetos

    2. Llame a la función de borrado del operador para liberar el espacio del objeto

  • El principio de la nueva T [N]

    1. Llame al operador new [] function, en realidad llame al operador new function en operator new [] para completar la aplicación de N espacios de objetos

    2. Ejecuta el constructor N veces en el espacio solicitado

  • El principio de eliminar []

    1. Realice N destructores en el espacio de objeto liberado para completar la limpieza de recursos en N objetos

    2. Llame al operador eliminar [] para liberar espacio, en realidad llame al operador eliminar en operador eliminar [] para liberar espacio

Preguntas comunes de entrevista

La diferencia entre malloc / free y new / delete

Lo que tienen en común malloc / free y new / delete es:

Todos solicitan espacio del montón y requieren que el usuario lo libere manualmente.

Las diferencias son:

  1. malloc y free son funciones, new y delete son operadores

  2. El espacio asignado por malloc no se inicializará, se puede inicializar nuevo

  3. Cuando malloc solicita espacio, debe calcular manualmente el tamaño del espacio y transferirlo. New solo necesita seguir el tipo de espacio.

  4. El valor de retorno de malloc es nulo *, debe obligarse a usarlo cuando se usa, no se necesita nuevo, porque nuevo es seguido por el tipo de espacio

  5. Cuando malloc no puede solicitar espacio, devuelve NULL, por lo que debe estar vacío cuando se usa, no se requiere nuevo, pero nuevo necesita detectar excepciones

  6. Al solicitar un objeto de tipo personalizado, malloc / free solo se abrirá y destruirá el espacio, y no llamará al constructor y al destructor. New llamará al constructor para completar la inicialización del objeto después de solicitar espacio, y delete llamará al análisis antes de liberar el espacio Constructor completa la limpieza de recursos en el espacio

  7. new / delete es un poco menos eficiente que malloc y es gratuito, porque la capa inferior de new / delete encapsula malloc / free

Diseñe una clase que solo pueda crear objetos en el montón

Privatización de constructores

  1. El constructor de la clase es privado y la construcción de la copia se declara privada. Evite que otros llamen copia para generar objetos en la pila.

  2. Proporcione una función miembro estática, complete la creación del objeto de montón en la función miembro estática

Ejemplo de código:

class HeapOnly
{
public:
    static HeapOnly * CreateObject()
    {      
        return new HeapOnly;
    }
private:
    HeapOnly() 
    {
    }
};

Diseñe una clase que solo pueda crear objetos en la pila

Ejemplo de código:

class StackOnly
{
public:
    static StackOnly CreateObject()
    {
        return StackOnly();
    }
private:
    StackOnly()
    {
    }
};

Los objetos solo se pueden crear en la pila, es decir, no se pueden crear en el montón, por lo que siempre que la función de nuevo esté protegida, es decir, el operador nuevo y las nuevas expresiones de posicionamiento están protegidas. Off

Ejemplo de código:

class StackOnly
{
public:
    StackOnly()  {}
private:
    void* operator new(size_t size);
    void operator delete(void* p);
};
152 artículos originales publicados · 45 elogiados · 10,000+ vistas

Supongo que te gusta

Origin blog.csdn.net/AngelDg/article/details/104902208
Recomendado
Clasificación