Gramática elemental de C++: nuevo, eliminar, crear/destruir espacio de memoria dinámica

Prefacio: en lenguaje C, malloc, realloc y calloc abren el espacio de memoria dinámica y liberan el espacio de memoria dinámica. En C++, use new para abrir espacio de memoria dinámica y eliminar para destruir el espacio de memoria dinámica. No sólo simplifica la operación, sino que, lo que es más importante,Resuelva el problema de inicialización de tipos personalizados.

1. Simplifique las operaciones

Uso: new 类型 delete 指针
Cree una matriz: new 类型[数据个数] delete[] 指针
el compilador calculará automáticamente el tamaño del tipo y no es necesario convertir el tipo. Esto simplifica enormemente la operación, pero recuerde las siguientes tres frases: ¡deben usarse de manera coincidente! ¡Combina para usar! ¡Combina para usar!

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

2. Resuelva el problema de la inicialización de tipos personalizados (énfasis)

La mayor diferencia entre new/delete y malloc/free es que new/delete no sólo abrirá espacio para tipos personalizados, sino tambiénLlame a sus constructores/destructores.
new llamará al constructor y eliminar llamará al destructor.

Tome la clase de pila como ejemplo:

typedef int DataType;
class Stack {
    
    
public:
	Stack(int capacity = 4)//构造函数 
	{
    
    
		_arr = new DataType[capacity];
		_capacity = capacity;
		_size = 0;
	}
	void StackPush(DataType Data)
	{
    
    
		_arr[_size] = Data;
		_size++;
	}
	~Stack() //析构函数
	{
    
    
		delete[] _arr;
		_capacity = _size = 0;
	}
private:
	DataType* _arr;
	int _capacity;
	int _size;
};
int main()
{
    
    
	Stack* ptr = (Stack*)malloc(sizeof(Stack)); //malloc开辟一个自定义的栈对象
	ptr->StackPush(1); //压栈
	free(ptr);
	return 0;
}

La consola muestra lo siguiente: Sabemos que un valor distinto de 0 significa un error de programa, entonces, ¿por qué aparece el error en el código anterior? Esto es lo que enfatizamos.malloc simplemente abre espacio y no llama al constructor del tipo personalizado Stack, no hay inicialización, y si empuja la pila hacia adentro sin inicialización, definitivamente ocurrirá un error.
Insertar descripción de la imagen aquí

Cambiar a nuevo y eliminar no informará un error:

int main()
{
    
    
	Stack* ptr = new Stack;
	ptr->StackPush(1);
	delete ptr;
	//free(ptr)  不行,free不会去调用析构函数,资源得不到清理。
	return 0;
}

3. new no comprueba si hay fallos y genera una excepción

Cuando usamos malloc para abrir espacio, generalmente escribimos una declaración condicional if para evitar que no se pueda abrir espacio, pero new ya no verifica si hay fallas y arrojará directamente una excepción cuando ocurre un error, es decir, cuando usamos nuevo, no es necesario escribir una condición if para evitar que no se pueda abrir espacio.

void Func()
{
    
    
	//malloc
	int* a = (int*)malloc(sizeof(int)*10);
	if (a == nullptr) //if判断
	{
    
    
		return;
	}
	free(a);
	//new
	int* b = new int[10];
	delete[] b;
}

1. Lanzar una excepción

Usar malloc para abrir un espacio del mismo tamaño no generará un error, pero lo hará un nuevo.
Insertar descripción de la imagen aquí

2. Captura de excepción (intenta capturar)

Utilice try y catch para detectar excepciones y encontrar la causa de la excepción.

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

La consola muestra lo siguiente:
Insertar descripción de la imagen aquí

Después de que ocurre una excepción, se produce un salto en el flujo de ejecución y el código después de la excepción no se ejecuta:

int main()
{
    
    
	try
	{
    
    
		cout << "正常" << endl;
		char* p2 = new char[0x7fffffff];
		cout << "异常" << endl;
	}
	catch (const exception& error)
	{
    
    
		cout << error.what() << endl;
	}
	return 0;
}

La salida de la consola es la siguiente: Se puede ver que el código que genera "anormal" no se ha ejecutado. Esto es similar a la declaración goto: después de que ocurre una excepción, salta directamente a la declaración catch. Este tipo de diseño evita ejecutar la siguiente declaración incluso si hay un error y evita que los errores se sumen a los errores.
Insertar descripción de la imagen aquí

Cuatro, función de nuevo operador/eliminación de operador

nuevo y eliminar son los operadores para que los usuarios soliciten y liberen memoria dinámica. Operador nuevo y eliminación de operador son funciones globales proporcionadas por el sistema. nuevo llama al operador nueva función global en la mazmorra para solicitar espacio, y eliminar utiliza el operador eliminar función global para liberarlo en el espacio inferior.

El operador nuevo es una encapsulación de la función malloc, es decir, el espacio generado por nuevo en realidad lo genera malloc. La diferencia es que la función malloc devolverá NULL si ocurre un error, pero C ++ necesita devolver una excepción si ocurre un error, por lo que la función malloc está encapsulada, pero un error devuelve una excepción.
El principio de eliminación del operador es similar al del operador.

De la siguiente manera: operador nuevo/operador eliminar se usa de la misma manera que malloc/free.

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

1. Tipos integrados

De lo anterior, si está solicitando un tipo de espacio integrado, nuevo y malloc, eliminar y liberar son básicamente similares. La diferencia es: nuevo/eliminar solicita y libera espacio para un solo elemento, mientras que nuevo[] y eliminar[] solicitan y liberan espacio continuo, y nuevo generará una excepción cuando no pueda solicitar espacio, y malloc regresará NULO.

Las siguientes tres formas pueden liberar espacio; de hecho, utilice gratis para liberar espacio. Pero no se recomiendan la primera y la segunda opción. Asegúrate de usaruso de partidos. para evitar circunstancias especiales.

	int* a = new int[10];
	//都可以释放申请的空间
	//free(a);
	//delete a;
	delete[] a;

2. Tipo personalizado

  1. El principio de nuevo
    1. Llame a la nueva función del operador para solicitar el espacio
    2. Ejecute el constructor en el espacio aplicado para completar la inicialización del objeto.
  2. El principio de eliminación
    1. Ejecute el destructor en el espacio para completar la limpieza de recursos en el objeto.
    2. Llame a la función de eliminación del operador para liberar el espacio del objeto.
  3. El principio de nueva T [n]
    1. Llame a la función del operador nuevo [] y, de hecho, llame a la función del operador nuevo en el operador nuevo [] para completar la aplicación de n espacios de objetos.
    2.Ejecutar el constructor n veces en el espacio solicitado
  4. El principio de eliminar []
    1. Ejecute n veces de destructores en el espacio de objetos liberado para completar la limpieza de recursos en n objetos.
    2. Llame al operador eliminar [] para liberar espacio y, de hecho, llame al operador eliminar en operador eliminar [] para liberar espacio.

BB al final del artículo: Si tiene alguna pregunta, no dude en dejar un mensaje en el área de comentarios. Si hay algún problema con algo escrito, puede señalarlo en el área de comentarios. El blogger hará correcciones tan pronto como sea posible después de verlo. Finalmente, no es fácil de hacer, si es útil para mis amigos, espero darle algunos me gusta y atención al blogger.

Insertar descripción de la imagen aquí

Supongo que te gusta

Origin blog.csdn.net/qq_73390155/article/details/132378490
Recomendado
Clasificación