C ++: The realization principle of new and delete


Operator new and operator delete functions

New and delete are operators for dynamic memory application and release by the user , operator new and operator delete are global functions provided by the system , new calls operator new global function at the bottom to apply for space, and delete uses the operator delete global function at the bottom to free up space .

/*
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)

Through the implementation of the above two global functions, it is known that operator new is actually applying for space through malloc . If malloc successfully applies for space , it will directly return. Otherwise, the countermeasures provided by the user to provide insufficient space will be executed. If the user provides this measure, continue to apply, otherwise Throw an exception. Operator delete eventually frees space through free.

Built-in type

If you are applying for a built-in type of space, new and malloc, delete and free are basically similar, the difference is: new / delete applies for and releases a single element of space, new [] and delete [] apply for continuous space And new will throw an exception when it fails to apply for space, and malloc will return NULL.

Custom type

  • The principle of new

    1. Call the operator new function to apply for space

    2. Execute the constructor on the requested space to complete the construction of the object

  • The principle of delete

    1. Executing destructors in space to complete the cleanup of resources in objects

    2. Call the operator delete function to free up the space of the object

  • The principle of new T [N]

    1. Call operator new [] function, actually call operator new function in operator new [] to complete the application of N object spaces

    2. Execute the constructor N times on the space requested

  • The principle of delete []

    1. Perform N destructors on the released object space to complete the cleaning of resources in N objects

    2. Call operator delete [] to free up space, actually call operator delete in operator delete [] to free up space

Common interview questions

The difference between malloc / free and new / delete

What malloc / free and new / delete have in common is:

All apply for space from the heap and require the user to manually release it.

The differences are:

  1. malloc and free are functions, new and delete are operators

  2. The space allocated by malloc will not be initialized, new can be initialized

  3. When malloc applies for space, you need to manually calculate the size of the space and transfer it. New only needs to follow the type of space.

  4. The return value of malloc is void *, it must be forced to use when used, new is not needed, because new is followed by the type of space

  5. When malloc fails to apply for space, it returns NULL, so it must be empty when used, new is not required, but new needs to catch exceptions

  6. When applying for a custom type object, malloc / free will only open up and destroy the space, and will not call the constructor and destructor. New will call the constructor to complete the initialization of the object after applying for space, and delete will call the analysis before releasing the space Constructor completes the cleanup of resources in space

  7. new / delete is slightly less efficient than malloc and free, because the bottom layer of new / delete encapsulates malloc / free

Please design a class that can only create objects on the heap

Constructor privatization

  1. The class constructor is private, and the copy construction is declared private. Prevent others from calling copy to generate objects on the stack.

  2. Provide a static member function, complete the creation of the heap object in the static member function

Code example:

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

Please design a class that can only create objects on the stack

Code example:

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

Objects can only be created on the stack, that is, they cannot be created on the heap, so as long as the function of new is shielded, that is, operator new and positioning new expressions are shielded. Note: shielding operator new actually shields positioning new Off.

Code example:

class StackOnly
{
public:
    StackOnly()  {}
private:
    void* operator new(size_t size);
    void operator delete(void* p);
};
Published 152 original articles · praised 45 · 10,000+ views

Guess you like

Origin blog.csdn.net/AngelDg/article/details/104902208