C++入门(内存管理)

文章目录

  • 1、New
  • 2、Delete
  • 3、operator new和operator delete
  • 4、定位New表达式(placement-new)
  • 5、内存泄漏

1、New

  • new在开辟空间的同时会自动调用类的默认构造函数进行初始化,默认构造对于内置类型不做处理,对于自定义类型会去调用自定义类型的默认构造
#include 
#include 

// 对于内置类型而言,用malloc和new,除了用法不同,没有什么区别
// 他们区别在于自定义类型, malloc只开空间,new开空间+调用构造函数初始化
struct ListNode
{
	ListNode* _next;
	int _val;

	ListNode(int val = 0)
		:_next(nullptr)
		, _val(val)
	{}
};

struct ListNode* BuyListNode(int x)
{
	struct ListNode* node = (struct ListNode*)malloc(sizeof(struct ListNode));
	assert(node);
	node->_next = NULL;
	node->_val = x;
	return node;
}

int main()
{
	int* p1 = new int; // New1个int对象
	int* p2 = new int[10]; // New10个int对象

	int* p3 = new int(10); // New一个int对象,初始化成10
	int* p4 = new int[10]{10, 1, 2, 3};// New10个int对象,初始化成{}中的值

	// 不匹配,可能会报错,可能不会报错。建议一定要匹配
	delete p1;
	delete[] p2;//与new int[10]匹配

	delete p3;
	delete[] p4;

	//ListNode* n1 = BuyListNode(1);
	ListNode* n1 = (struct ListNode*)malloc(sizeof(struct ListNode));
	assert(n1);

	ListNode* n2 = new ListNode(2);
	ListNode* n3 = new ListNode(3);
	ListNode* n4 = new ListNode(4);

	return 0;
}

2、Delete

  • delete在销毁空间的同时会自动调用类的析构函数,析构函数对于内置类型不做处理,对于自定义类型会去调用自定义类型的析构函数
class Stack
{
public:
	Stack(int capacity = 0)
	{
		cout << "Stack(int capacity)" << endl;
		_a = new int[capacity];
		_capacity = capacity;
		_top = 0;
	}

	~Stack()
	{
		cout << "~Stack()" << endl;
		delete[] _a;
		_capacity = 0;
		_top = 0;
	}

class MyQueue {
public:
	MyQueue()
		: _pushST(4)
		, _popST(4)
	{}
private:
	Stack _pushST;
	Stack _popST;
};

int main()
{
	Stack st;
	Stack* ps1 = (Stack*)malloc(sizeof(Stack));
	assert(ps1);
    Stack* ps2 = new Stack; // 开空间+调用构造函数初始化

	free(ps1);
	delete ps2; // 调用析构函数清理资源 + 释放空间

	MyQueue* obj = new MyQueue;
	delete obj;

	return 0;
}

3、operator new和operator delete

operator new和operator delete是两个C++提供的库函数

int main()
{ 
	// 跟 malloc功能一样, 失败以后抛异常
	Stack* ps2 = (Stack*)operator new(sizeof(Stack));
	operator delete(ps2);

	Stack* ps1 = (Stack*)malloc(sizeof(Stack));
	assert(ps1);
	free(ps1);

	//new的底层原理,就是转换成了调用operator new和构造函数
	Stack* ps3 = new Stack;
	// call operator new
	// call Stack构造函数

	return 0;
}

4、定位New表达式(placement-new)

  • 定位new表达式是在已分配的原始内存空间中调用构造函数初始化一个对象。
  • 使用格式:
    new (place_address) type或者new (place_address) type(initializer-list)
    place_address必须是一个指针,initializer-list是类型的初始化列表
int main()
{
	Stack* obj = (Stack*)operator new(sizeof(Stack));
	// 针对一个空间,显示调用构造函数初始化
	new(obj)Stack(4);

	return 0;
}

5、内存泄漏

1、内存泄漏是指针丢了,内存还没有释放,无法将这块空间还给内存

你可能感兴趣的:(c++,算法,c语言)