C++ Elementary Grammar – new, delete create/destroy dynamic memory space

Preface: In C language, there are malloc, realloc, calloc to open up dynamic memory space, and free to destroy dynamic memory space. In C++, use new to open up dynamic memory space, and delete to destroy dynamic memory space. It not only simplifies the operation, but more importantly, solves the initialization problem of custom types.

Table of Contents

  • 1. Simplify operations
  • 2. Solve the problem of custom type initialization (emphasis)
  • 3. New does not check for failure and throws an exception.
    • 1. Throw an exception
    • 2. Catch exceptions (try catch)
  • 4. operator new/operator delete function
    • 1. Built-in types
    • 2. Custom type

1. Simplify operation

Usage: new type delete pointer
Create an array: new type [number of data] delete[] pointer
The compiler will automatically calculate the size of the type, and there is no need to cast the type. It greatly simplifies the operation, but remember the following three sentences: Be sure to match and use! Match to use! Match to use!

 //int* a = (int*)malloc(sizeof(int));
//free(a);
int* a = new int;
delete a;
int* b = new int[10];
delete[] a;

2. Solve the problem of custom type initialization (key point)

The biggest difference between new/delete and malloc/free is that new/delete will call their constructors/destructors in addition to opening space for custom types.
new will call the constructor and delete will call the destructor.

Take the stack class as an example:

typedef int DataType;
class Stack {<!-- -->
public:
Stack(int capacity = 4)//constructor
{<!-- -->
_arr = new DataType[capacity];
_capacity = capacity;
_size = 0;
}
void StackPush(DataType Data)
{<!-- -->
_arr[_size] = Data;
_size + + ;
}
~Stack() //Destructor
{<!-- -->
delete[] _arr;
_capacity = _size = 0;
}
private:
DataType* _arr;
int _capacity;
int _size;
};
int main()
{<!-- -->
Stack* ptr = (Stack*)malloc(sizeof(Stack)); //malloc opens up a custom stack object
ptr->StackPush(1); //Push the stack
free(ptr);
return 0;
}

The console displays as follows: We know that non-0 means a program error, so why does the above code error? This is what we emphasize malloc just opens up space and will not call the constructor of the custom type Stack, so there is no initialization. If you push the stack without initialization, an error will definitely occur.

Changing to new and delete will not report an error:

int main()
{<!-- -->
Stack* ptr = new Stack;
ptr->StackPush(1);
delete ptr;
//free(ptr) No, free will not call the destructor, and the resources will not be cleaned up.
return 0;
}

Three. new does not check for failure, throws an exception

When we use malloc to open up space, we usually write an if conditional statement to prevent failure to open up space, but new no longer checks for failure, and will directly throw an exception when an error occurs. That is to say, when using new, there is no need to write an if condition to prevent failure to open up space.

void Func()
{<!-- -->
//malloc
int* a = (int*)malloc(sizeof(int)*10);
if (a == nullptr) //if judgment
{<!-- -->
return;
}
free(a);
//new
int* b = new int[10];
delete[] b;
}

1. Throw an exception

Using malloc to open a space of the same size will not prompt an error, but new will.

2. Catch exception (try catch)

Use try and catch to catch exceptions and find the cause of the exception.

int main()
{<!-- -->
try
{<!-- -->
char* p2 = new char[0x7fffffff];
}
catch (const exception & error)
{<!-- -->
cout << error.what() << endl;
}
\t

The console shows the following:

After an exception occurs, an execution flow jump occurs, and the code after the exception is not executed:

int main()
{<!-- -->
try
{<!-- -->
cout << "normal" << endl;
char* p2 = new char[0x7fffffff];
cout << "Exception" << endl;
}
catch (const exception & error)
{<!-- -->
cout << error.what() << endl;
}
return 0;
}

The console output is as follows: It can be seen that the code that outputs “exception” has not been executed. This is similar to the goto statement. After an exception occurs, it jumps directly to the catch statement. This design avoids running subsequent statements when an error occurs, and prevents mistakes from being compounded.

Four.operator new/operator delete function

new and delete are the operators for users to apply for and release dynamic memory. Operator new and operator delete are global functions provided by the system. new calls the operator new global function in the dungeon to apply for space, and delete uses the operator delete global function to release it at the bottom. space.

operator new is an encapsulation of the malloc function, that is to say, the space generated by new is actually generated by malloc. The difference is that the malloc function returns NULL when an error occurs, and C++ requires an error return exception, so the malloc function is encapsulated, but an error return exception occurs.
The principle of operator delete is similar to operator.

As follows: operator new/operator delete is used in the same way as malloc/free.

 int* a = (int*)malloc(sizeof(int) * 10);
free(a);
int* b = (int*)operator new(sizeof(int) * 10);
operator delete(b);

1. Built-in types

From the above, 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 space for a single element, while new[] and delete[] apply for and releases continuous space, and new will throw an exception when it fails to apply for space, and malloc will return NULL.

The following three ways can free up space, in fact, use free to free up space. But the first and second options are not recommended. Be sure to match the usage when using it. to avoid special situations.

 int* a = new int[10];
//You can release the applied space
//free(a);
//delete a;
delete[] a;

2. Custom type

  1. 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 object initialization.
  2. The principle of delete
    1. Execute the destructor on the space to complete the cleanup of resources in the object.
    2. Call the operator delete function to release the space of the object.
  3. The principle of new T[n]
    1. Call the operator new[] function, and actually call the operator new function in operator new[] to complete the application of n object spaces.
    2. Execute the constructor n times on the requested space.
  4. The principle of delete[]
    1. Execute n times of destructors on the released object space to complete the cleanup of resources in n objects.
    2. Call operator delete[] to release space, and actually call operator delete in operator delete[] to release space.

BB at the end of the article: If you have any questions, feel free to leave a message in the comment area. If there is something wrong with something written, you are welcome to point it out in the comment area. The blogger will make corrections as soon as possible after seeing it. Finally, it is not easy to make. If it is helpful to friends, I hope to give bloggers some likes and attention.