- C++内存分配方式
一个进程被分配的虚拟内存空间包含以下几个区域(从低地址向高地址):文字常量区、代码区、全局区(.data/.bss)、堆区、共享库存储器映射区、栈区、用户栈(存储命令行参数和环境变量)。
对于这几个区存储的什么内容前面博客有介绍。虚拟内存空间一般是从0x0000 0000-0xffff ffff,大于共4G,前3G是用户空间,后1G是内核空间。
栈的大小可以设置,在类UNIX平台上,可以在环境变量中设置栈的大小,在Windows平台下,栈的大小在可执行文件当中,一般情况下,不同平台栈空间默认大小如下:SunOS/Solaris 8172K bytes (Shared Version),约8M
Linux 10240K bytes,约10M
Windows 1024K bytes (Release Version),约1M
AIX 65536K bytes,是2^16,约128M
堆大小是可以自己申请的,只要不超过内存都是可以的,最大多少不知道,怎么着都不会超过4G吧。
malloc/free作用于堆上,new/delete作用于自由存储区。但是由于new是c语言中malloc的简单包装,所以调用系统的new操作符分配的空间其实还是在堆上,所以new操作符分配的对象说它在堆上也合适,说它在自由存储区也合适。但是如果重载new操作符,改用在其他地方分配内存,那么自由存储区的位置就发生了变化,比如可以在全局区。 - C++常用内存分配函数
有new()/delete()、new[]/delete[]、malloc/free,calloc,realloc。// 这4个版本可能抛出异常 void *::operator new(size_t); // 分配一个对象 void *::operator new[](size_t); // 分配一个数组 void *::operator delete(void*) noexcept; // 释放一个对象 void *::operator delete[](void*) noexcept; // 释放一个数组 // 这些版本承若不会抛出异常 void *::operator new(size_t, nothorw_t &); // 分配一个对象 void *::operator new[](size_t, nothorw_t &); // 分配一个数组 void *::operator delete(void*, nothorw_t &) noexcept; // 释放一个对象 void *::operator delete[](void*, nothorw_t &) noexcept; // 释放一个数组太难了,写不出来,内存管理都是用一本书来介绍的。
1.不光有系统给的内存分配函数,还可以重载new/delete、new[]/delete[]操作符来实现不同的内存分配策略。
2.内存分配错误的几种情况以及应对策略。
3.内存耗尽应对策略
4.C++智能指针管理内存
5.内存泄漏定义、内存泄漏发生方式、检测工具以及解决方案
6.C++内存回收
7.三种内存对象
8.C++垃圾回收方法
下面回答一下常见问题吧 -
为什么有了malloc/free还要有new/delete?
首先必须明确malloc/free是标准库函数,new/delete是运算符。对于非内部对象,无法通过malloc/free来为其动态分配内存,但是new/delete可以,new/delete操作符可以调用构造和析构函数为非内部对象初始化和删除,这些malloc/free都不能做。new/delete能做malloc/free能做的,也能做它不能做的,那是不是可以淘汰malloc/free呢?不可以,因为new函数的实现实际上是对C语言中malloc的简单包装,所以不能淘汰。#include <iostream> using namespace std; class Obj{ public: Obj(void){ cout<<" Construct1"<<endl; }; Obj(int x):data(x){ cout<<" Construct2"<<endl; } ~Obj(){ cout<<" destruct"<<endl; } private: int data; }; void Test(void){ Obj *a=new Obj; Obj *b=new Obj(1); delete a; delete b; } int main(){ Test(); return 0; }输出结果:
Construct1
Construct2
destruct
destruct -
malloc/free、new/delete使用要点
malloc申请一段内存:void * malloc(size_t); int *p=(int *)malloc(sizeof(int)*10); 返回类型为void *,所以需要强制类型转换(int *) void free(void* membolck); free(p); 被分配的内存重复free会导致程序运行错误,但是对null指针重复释放不会报错。new的用法
new一个对象 int *p=new int(2);//为一个整型数据分配内存空间 delete p; new一个数组 int *p=new int[len];//申请一段内存空间 int *p=new int[len]();//初始化为0 delete[] p;new一个自定义对象数组
#include <iostream> using namespace std; class Obj{ public: Obj(void){ cout<<" Construct1"<<endl; }; Obj(int x):data(x){ cout<<" Construct2"<<endl; } ~Obj(){ cout<<" destruct"<<endl; } int data; }; void Test(void){ Obj *p=new Obj[10]; for(int i=0;i<10;++i){ (p+i)->data=i; } delete[] p; } int main(){ Test(); return 0; }输出结果:
Construct1
Construct1
Construct1
Construct1
Construct1
Construct1
Construct1
Construct1
Construct1
Construct1
destruct
destruct
destruct
destruct
destruct
destruct
destruct
destruct
destruct
destruct -
通过new实现对象的深拷贝
C++内存管理技术内幕
最新推荐文章于 2026-01-22 00:34:29 发布
本文探讨了C++内存管理的各个方面,包括内存区域、栈与堆的特性、常用的内存分配函数如new/delete、malloc/free等。还提到了内存分配错误处理、智能指针、内存泄漏检测及解决方案、内存回收以及C++中的内存对象和垃圾回收方法。着重指出new/delete相比于malloc/free的优势在于能够处理对象的构造和析构。

3014

被折叠的 条评论
为什么被折叠?



