自学C++ day03 (内存管理)

#include <iostream> 
#include <cstring>
using std::cout;
using std::endl;

// C++ 进程内存分布:
#if 0
int global_var = 1; // 数据段(静态数据,全局数据区)
static int static_global_val = 1; // 数据段(静态数据,全局数据区)
void Test() {
	static int static_val = 1; // 数据段(静态数据,全局数据区)
	int local_val = 1;// 栈区
	int num1[10] = { 0 }; // num1 栈区, 数据堆区!
	char char2[] = "abcd"; // char2 在栈区, "abcd" 在代码段(可执行代码/只读常量);
	char *pchar3 = "abcd"; // pchar3 在栈区, "abcd" 在代码段(可执行代码/只读常量);
	int *ptr1 = (int*)malloc(sizeof(int) * 4); // ptr1 栈区, = 右边堆区
	int *ptr2 = (int*)calloc(4, sizeof(int)); // ptr2 栈区, = 右边堆区
	int *ptr3 = (int*)realloc(ptr2, sizeof(int) * 4);// ptr3 栈区, = 右边堆区
	free(ptr1);// 栈区
	free(ptr2);// 栈区
}

// 栈: 又叫堆栈,非静态局部变量/函数参数/返回值等存放!
// 内存映射段: 又称共享区,用于装载共享的动态内存库,共享内存(用于进程通信);
// 堆: 用于程序运行时动态分配内存!
// 数据段: 存储全局数据和静态数据!
// 代码段: 可执行代码/只读常量!

// C 中动态内存管理方式: malloc / calloc / realloc 

// new delete 动态内存管理:

// 1. new/delete 操作内置类型:
void Test() {
	// 动态申请一个int类型的空间!
	int *ptr1 = new int;

	// 动态申请一个int类型的空间并初始化为10
	int *ptr2 = new int(10);

	// 动态申请10个int类型的空间!
	int *ptr3 = new int[10];

	delete ptr1;
	delete ptr2;
	delete[] ptr3;
}
// 申请和释放单个元素空间,使用new和delete操作符,申请和释放连续的空间,使用new[] 和delete[] 

//2. new 和 delete 操作自定义类型

class Test {
public:
	Test():_data(0){}
	~Test() {
		cout << "~Test()" << endl;
	}
private:
	int _data;
};
void Test2() {
	Test *p1 = (Test*)malloc(sizeof(Test));
	free p1;

	Test *p2 = (Test*)malloc(sizeof(Test) * 10);
	free p2;
}


void Test3() {
	Test *p1 = new Test;
	delete p1;

	Test *p2 = new Test[10];
	delete[] p2;
}
#endif 

// 3. operator new 与 operator delete 
// new 在底层调用operator new 全局函数来申请空间
// delete 在底层调用operator delete 释放空间!
// operator new 实际也是通过malloc 申请空间!
// operator delete 最终是通过free释放空间!

// eg: 通过重载operator new /opreator delete 实现链表节点的内存池申请和释放内存!
#if 0
struct ListNode {
	ListNode *_next;
	ListNode *_prev;
	void* operator new(size_t n){
		void* p = nullptr;
		p = allocator<ListNode>().allocate(1);
		cout << "memeoy pool allocate " << endl;
		return p;
	}
	void operator delete(void* p) {
		allocator<ListNode>().deallocate((ListNode*)p, 1);
		cout << "memory pool deallocate" << endl;
	}
};
#endif 

// new 和 delete 实现原理
// 如果申请的是内置类型的空间,new 和 malloc ,delete 和 free 基本类似!
// 不同的地方是: new/delete 申请和释放的是单个元素的空间,new[] 和 delete[] 申请的是连续的空间,而且new 在申请空间失败是会抛异常!
// malloc 会返回NULL

// new : (1)调用 operator new 函数申请空间;(2) 在申请的空间上执行构造函数,完成对象构造!
// delete: (1) 在空间上执行析构函数,完成对象中资源的清理工作; (2) 调用operator delete 函数释放对象的空间!
// new T[N] : (1) 调用 operator new[] 函数在operator new[] 中实际调用operator new 完成堆空间的申请; (2) 在空间上执行N次构造函数!
// delete[] : (1) 在释放的对象空间上执行N次析构函数,完成N个对象中的资源清理; (2) 调用operator delete[] 释放空间,实际也是调用operator delete;

// 定位new表达式, new (T* ptr) type (initlializer-list) 在指针ptr所在空加上根据初始化列表创建对象!


// 内存泄露:
// 因为疏忽或错误造成程序未能释放已近不再使用的内存的情况!
// 内存泄露不是指内存在物理上消失,而是应用程序在分配某段内存后,因为设计错误,失去了对该段内存的控制,
// 因而造成了内存的浪费; 
// 如果程序长期运行,则内存泄露的影响很大!

// 内存泄露分类:
// Heap leak : 堆内存泄露!
// 系统资源泄露,比如套接字,文件描述符,管道等!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值