行业知识
C++初阶:C/C++内存管理、new与delete详解
2026-11-01 14:13:48
来源:互联网转载
之前���束了类与对象:今天进行下面部分内容的学习
文章目录
- 1.C/C++内存分布
- 2.C语言中动态内存管理方式:malloc/calloc/realloc/free
- 3.C++动态内存管理方式
- 3.1new/delete操作内置类型
- 3.2new和delete操作自定义类型
- 4.operator new与operator delete函数
- 5.new和delete的实现原理
- 5.1内置类型
- 5.2自定义类型
- 6.定位new表达式(placement-new)
- 7.知识点梳理
- malloc/free和new/delete的区别
1.C/C++内存分布
具体说明:
- 栈又叫堆栈–非静态局部变量/函数参数/返回值等等,栈是向下增长的。栈上的内存分配和释放是通过编译器生成的代码来管理的,通常是通过在函数退出时进行清理来实现的
- 内存映射段是高效的I/O映射方式,用于装载一个共享的动态内存库。用户可使用系统接口创建共享共享内存,做进程间通信
- 堆用于程序运行时动态内存分配,堆是可以上增长的。堆上的内存通常需要手动管理,需要显式地分配和释放堆上的内存
- 数据段–存储全局数据和静态数据。全局数据和静态数据的销毁通常是在程序结束时由操作系统自动完成,二者的生命周期也是整个程序
- 代码段–可执行的代码/只读常量
下面根据具体代码来看:
int globalVar = 1;//全局变量,在静态区static int staticGlobalVar = 1;//全局静态变量,在静态区int main(){static int staticVar = 1;//局部静态变量,在静态区。作用域只在这个函数内,但是生命周期是在整个程序int localVar = 1;//局部变量,在栈int num1[10] = { 1, 2, 3, 4 };//局部变量,在栈char char2[] = "abcd"; //局部变量,在栈。//其实[]这个符号:是把位于常量区的"abcd",拷贝到栈上,再去指向const char* pChar3 = "abcd";//pChar3在栈上,但是是直接指向常量区的"abcd"。所以*pChar3在常量区int* ptr1 = (int*)malloc(sizeof(int) * 4);//ptr1这个指针变量还是在栈,但是*ptr1是在堆上int* ptr2 = (int*)calloc(4, sizeof(int));int* ptr3 = (int*)realloc(ptr2, sizeof(int) * 4);free(ptr1);free(ptr3);return 0;}那全局变量和全局静态变量的区别是??
全局变量具有外部链接性,可以被其他文件中的函数访问。
静态全局变量具有内部链接性,只能被声明它的文件内的函数访问(本文件)
2.C语言中动态内存管理方式:malloc/calloc/realloc/free
- malloc()函数:
- 功能:malloc函数用于在堆上动态分配指定大小的内存空间。
- 语法:void* malloc(size_t size);
- 返回值:如果分配成功,则返回指向分配内存的指针;如果分配失败,则返回NULL。
- calloc()函数:
- 功能:calloc函数用于在堆上动态分配指定数量、指定大小的内存空间,并将分配的内存空间初始化为0。
- 语法:void* calloc(size_t num, size_t size);
- 返回值:如果分配成功,则返回指向分配内存的指针;如果分配失败,则返回NULL。
- realloc()函数:
- 功能:realloc函数用于更改之前分配的内存块的大小,可以扩大或缩小内存块的大小。
- 语法:void* realloc(void* ptr, size_t size);
- 返回值:如果分配成功,则返回指向重新分配内存的指针;如果分配失败,则返回NULL。如果返回的指针与之前的指针不同,意味着内存块的大小或位置可能已经改变了。
- free()函数:
- 功能:free函数用于释放之前动态分配的内存空间,将其返回给系统供其他程序使用。
- 语法:void free(void* ptr);
- 返回值:无。
异同点:
- malloc和calloc都用于分配内存,但calloc在分配内存后会将其初始化为0,而malloc不会。
- realloc用于更改之前分配的内存块的大小,可以扩大或缩小内存块的大小,而malloc和calloc只能用于分配新的内存块。
- free用于释放动态分配的内存,将其返回给系统供其他程序使用
更加详细的介绍大家可以移步于我的文章:
3.C++动态内存管理方式
C语言内存管理方式在C++中可以继续使用,但有些地方就无能为力(特别是关于自定义变量),因此C++又提出了自己的内存管理方式:通过new和delete操作符进行动态内存管理
在C++中,new和delete是用于动态内存管理的运算符,它们提供了对malloc、calloc、realloc和free等C语言内存管理函数的更高级的封装和功能。
- new运算符:
- 功能:new运算符用于在堆上动态分配内存,并调用对象的构造函数来初始化这块内存。
- 语法:new 类型 或 new 类型[大小],例如:new int 或 new int[10]。
- 返回值:如果分配成功,则返回指向分配内存的指针;如果分配失败,则抛出std::bad_alloc异常。
- delete运算符:
- 功能:delete运算符用于释放由new分配的内存,并调用对象的析构函数来销毁对象。
- 语法:delete 指针 或 delete[] 指针,例如:delete ptr 或 delete[] arr。
- 返回值:无。
与C语言中的malloc和free相比,new和delete的优势在于:
- new和delete是运算符,而不是函数,因此它们可以重载,从而实现自定义的内存分配和释放策略。
- new和delete会调用对象的构造函数和析构函数,从而确保对象的正确初始化和清理。
- new和delete支持运算符重载,可以用于自定义类的动态内存管理,而malloc和free只能用于分配和释放原始内存块
3.1new/delete操作内置类型
直接上代码:
int main(){// 动态申请一个int类型的空间int* a = new int;// 动态申请一个int类型的空间并初始化为11int* b = new int(11);// 动态申请3个int类型的空间int* c = new int[3];// 动态申请10个int类型的空间,并进行部分初始化int* d = new int[10]{ 1,2,3 };delete a;delete b;delete[] c;delete[] d;return 0;}内置类型的对象申请释放,new和malloc除了用法上,没有区别
但是malloc不方便解决动态申请的自定义类型对象的初始化问题,不会调用构造函数
3.2new和delete操作自定义类型
class A{public:A(int a=0):_a(a){}~A(){cout nBlockUse);__FINALLY_munlock(_HEAP_LOCK); __END_TRY_FINALLYreturn;}看到:其实operator new 实际也是通过malloc来申请空间。operator delete 最终是通过free来释放空间的
二者其实就是对malloc和free进行了封装,加上了抛出异常的修饰
5.new和delete的实现原理
5.1内置类型
如果申请的是内置类型的空间,new和malloc,delete和free基本类似,不同的地方是:
new/delete申请和释放的是单个元素的空间,new[]和delete[]申请的是连续空间,而且new在申请空间失败时会抛异常,malloc会返回NULL。
5.2自定义类型
- new的原理
- 调用operator new(跟malloc效果一样)函数申请空间
- 在申请的空间上执行构造函数,完成对象的构造
- delete的原理
- 在空间上执行析构函数,完成对象中资源的清理工作(先调用析构函数,释放成员变量申请的空间,不然会找不到)
- 调用operator delete函数释放对象的空间
- new TYPENAME[N]的原理
- 调用operator new[]函数,在operator new[]中实际调用operator new函数完成N个对象空间的申请(一次性申请)
- 在申请的空间上执行N次构造函数
- delete[]的原理
- 在释放的对象空间上执行N次析构函数,完成N个对象中资源的清理
- 调用operator delete[]释放空间,实际在operator delete[]中调用operator delete来释放空间
但是要注意一件事:
class Stack{public:Stack(int capacity = 3){cout
- new的原理
- new运算符:
- malloc/free和new/delete的区别
上一篇:网站怎么上传成功案例?
下一篇:不搭建服务器怎么运行json?