#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 : 堆内存泄露!
// 系统资源泄露,比如套接字,文件描述符,管道等!
自学C++ day03 (内存管理)
最新推荐文章于 2024-11-11 22:14:43 发布