Explore the secrets of new and delete

Introduction:
  new and delete are two operators used by C++ to manage heap memory. malloc and free in C language are functions, while new and delete are operators in C++. Both malloc and new are dynamically allocated memory.


.With malloc and free, why should there be new and delete?

  1. malloc and free are standard library functions in C++/C language, and new/delete are operators in C++, both of which can be used to apply for and release memory.
  2. For objects of non-internal data types, malloc and free alone cannot meet the requirements of dynamic objects: when an object is created, it needs to start calling the constructor, and when the object is destroyed, it automatically calls the destructor, because malloc and free are Library functions are not operators, and they are not under compilation control. They cannot be assigned the task of calling constructors and destructors. Therefore, the C++ language needs an operator that can complete [dynamic memory allocation and initialization, as well as a free memory and cleanup. operator, namely new/delete], that is, new/delete will call the constructor and destructor
  3. New passes the number of objects , and malloc passes the number of bytes.
  4. new/delete can be overloaded

. Why malloc and free failed to be eliminated

  From the above, we can see that the function of new/delete completely includes malloc/free, and there are improvements on its basis. Why does C++ not eliminate malloc/free?  

  1. C++ programs are compatible with everything in C, so C++ sometimes calls some C programs, but only malloc/free can be used to dynamically manage memory in C programs.
  2. In some cases, malloc/free can provide higher efficiency than new/delete.

. malloc, free use:

  malloc/free

Use of .new and delete:

  Knock on the blackboard! Knock on the blackboard! Knock on the blackboard!
  Let's put the use example first:

int* p1=new int;//动态分配4个字节(1个int)的空间单个数据
int* p2=new int(3);//分配4个字节(1个int)并初始化为3
int* p3=new int[3];  //动态分配12个字节(3个int)的空间
  1. The internal implementation of the new operator:
      As mentioned earlier, new is specially designed for C++ to create dynamic objects. Its function is: dynamically allocate memory + initialize the object (that is, call the constructor), then when allocating memory is it like and The same implementation mechanism as malloc? The answer is of course not.
      new will call the corresponding operator new(size_t) function, and then call malloc to dynamically allocate memory. If operator new(size_t) fails to obtain memory successfully, the new_handler() function is called to handle the new failure problem and an exception is thrown. After allocating the space, initialize the object of the corresponding type (ie the constructor) on the allocated dynamic memory block and return its first address. If an exception is thrown when calling the constructor to initialize the object, the operator delete(void*, void*) function is automatically called to release the allocated memory.
      That is, new is divided into two parts: calling operator new to allocate space + calling the constructor to initialize the object.
      Laitu Town Building:
       write picture description here

  2. Internal implementation of delete operator:
      The function of delete is just the opposite of that of new. If you allocate space with new and call the constructor, then I delete is to face you. The function of my delete is to call the destructor and release the space (note the order) ).
      Your new has a corresponding implementation mechanism of operator new, then I delete also has a corresponding implementation mechanism, that is, operator delete.
      So delete is divided into two steps: calling destructor to clean up + calling operator delete to release space.
      Laitu Town Building:
      write picture description here

Sublimation of .new/delete:

  1. The biggest difference between new/delete and malloc/free is the way errors are handled:
      malloc/free is process-oriented. Procedural language errors are handled by return values.
      And new/delete is object-oriented, an error will throw an exception.
    But we also found that the bottom layer of new/delete actually calls malloc/free, so how do they implement throwing exceptions, in fact, operator new and operatoe delete between them play a role. Operator new/delete has encapsulation, encapsulates malloc/free, makes it conform to the specification of object-oriented language, and achieves the purpose of throwing exceptions by mistake.

  2. For object arrays:
      What is an object array? Go directly to the code town building:

class AA {
public:
   AA()
   {
     _a = new int[10];
     cout << "AA()" << endl;
   }
   ~AA()
   {
      delete[] _a;
      cout << "~AA()" << endl;
   }
private:
   int* _a;
};
void Test()
{
    AA* p1=new AA[10];//创建了十个对象,即对象数组
    delete[] p1;
}

  So the question is, there is no problem with the previous new object and delete to clean up an object, so for now, 10 objects have been new, so how does delete know how many objects to clean up, that is, how many times to call the destructor?
  The answer is: when new opens up space, four more bytes will be allocated to store the number of opened objects. For example, the above example requires the size of 10 objects to be opened, so the number 10 will be stored in the four extra bytes allocated. , so that delete can call the destructor 10 times. But when there is no user-defined destructor in the class, those four more bytes are not allocated. That is: four more bytes are allocated depending on whether there is a user-defined destructor.
  So new[n] does the following things:
   calling operator new to allocate space + calling N times the constructor to initialize each object respectively.
  Similarly delete[n] does these things:
   calling the destructor N times to clean up the object + calling operator delete frees space
  write picture description here
  So another question arises, the matching use of new and delete?

. new, delete and new[], delete[] matching use:

  Old rules, go to the code town building:

class AA {
public:
        AA()
        {
               _a = new int[10];
               cout << "AA()" << endl;
        }
        ~AA()
        {
               delete[] _a;
               cout << "~AA()" << endl;
        }
private:
        int* _a;
};
void Test()
{
    int* p1 = new int[10];
    free(p1);//new分配空间-->operator new-->malloc   free释放
    AA* p2 = (AA*)malloc(sizeof(AA));//没有调用构造函数
    delete p2;//分配空间malloc(没有调用构造函数),倘若构造函数有初始化,则这种方式
              //会将构造函数里的值=随机值,再次调用delete会将随机值释放,错误
    int* p3 = new int[10];//过程:new-->operator new-->malloc
    delete p3;//过程:delete-->operator delete-->free

    AA* p4 = new AA[10];//error(只调用了一次析构)
    delete p4;

    AA* p1 = new AA[10];//开空间,调用10次构造函数,多分配了四个字节
    delete[] p1;//调用10次析构函数+释放空间
}

Finally, thank you for your patience and send pictures to town:
write picture description here

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326678061&siteId=291194637