深入理解C++动态内存管理

本文深入探讨了C++的动态内存管理,包括C语言中的malloc、calloc、realloc、free和C++中的new、delete、new[]/delete[]。重点讨论了new与malloc的区别,new在分配内存的同时会调用构造函数,而delete则会调用析构函数。此外,还提到了operator new和operator delete的作用以及定位new表达式。
摘要由CSDN通过智能技术生成
1. 对比C语言和C++的动态内存管理
2. 探索静态内存管理和动态内存管理
3. 理解什么是内存泄露及内存泄露的危害
4. new/delete 和operator new/operator delete和malloc/free的关系 
5. new[]时底层处理的机制 
6. new/delete和malloc/free的区别 

C语言动态内存管理

C语言使用malloc、calloc、realloc、free进行动态内存管理。

void Test ()
{
int* p1 = (int*) malloc (sizeof (int)*4);
free(p1 );
// 1.calloc/realloc/malloc 的区别是什么?
int* p2 = (int*) calloc(4, sizeof (int));
int* p3 = (int*) realloc(p2 , sizeof( int)*6);
// 这里需要free(p2)吗?
free(p1);
free(p3 );
}

C++动态内存管理

C++通过new和delete动态内存管理内存。
new、delete动态管理对象。
new[]/delete[]动态管理对象数组。
这里写图片描述

void Test ()
{
int* p4 = new int; // 动态分配4个字节(1个 int)的空间单个数据
int* p5 = new int(3); // 动态分配4个字节(1个 int)的空间并初始化为3
int* p6 = new int[3]; // 动态分配12个字节(3个 int)的空间
delete p4 ;
delete p5 ;
delete[] p6 ;
}
- 注意malloc/free、new/delete、new[]/delete[]
一定要匹配使用,一定要匹配使用!!!否则可能出现内存泄漏甚至崩溃的问题

内存管理

int globalVar = 1;
static int staticGlobalVar = 1;
void Test ()
{
// 1.全局变量、全局静态变量、局部静态变量、局部变量之间的区别是什么?
static int staticVar = 1;
int localVar = 1;
// 2.下面的a1和 a2和a3 有什么区别和联系?
int a1[10] = {1, 2, 3, 4};
char a2 [] = "abcd";
char* a3 = "abcd";
int * p1 = ( int*) malloc (sizeof ( int)*4);
int * p2 = ( int*) calloc (4, sizeof ( int));
int * p3 = ( int*) realloc (p2 , sizeof( int )*4);
free (p1 );
free (p3 );
int * p4 = new int;
int * p5 = new int(3);
int * p6 = new int[3];
delete p4 ;
delete p5 ;
delete [] p6 ;
}

这里写图片描述

  1. 栈又叫堆栈,非静态局部变量、函数参数、返回值等等,栈是向下增长的。
  2. 内存映射段是高效的 I/O映射方式,用于装载一个共享的动态内存库。用户可使用系统接口创建共享内容,做进程间通信
  3. 堆用于程序运行时动态内存分配,堆是可以向上增长的。
  4. 数据段—-存储全局数据和静态数据。
  5. 代码段—-可执行的代码(只读常量)

深入理解C++动态内存管理

【malloc/free和new/delete的区别和联系?】

  1. 他们都是动态管理内存的入口
  2. malloc/free是C/C++标准库的函数,new/delete是C++操作符。
  3. malloc/free只是动态分配内存空间、释放空间。而new/delete除了分配空间还会调用构造函数和析构函数进行初始化与清理(清理成员)
  4. malloc/free需要计算类型大小且返回值为void*,new/delete可自己计算类型的大小,返回对应的类型的指针。
class Array
{
public :
Array (size_t size = 10)
: _size(size )
, _a(0)
{
cout<<"Array(size_t size)" <<endl;
if (_size > 0)
{
_a = new int[ size];
}
}
~ Array()
{
cout<<"~Array()" <<endl;
if (_a )
{
delete[] _a ;
_a = 0;
_size = 0;
}
}
private :
int*_a ;
size_t _size ;
};
void Test ()
{
Array* p1 = (Array*) malloc(sizeof (Array));
Array* p2 = new Array;
Array* p3 = new Array(20);
Array* p4 = new Array[10];
free(p1 );
delete p2 ;
delete p3 ;
delete[] p4 ;
}
  • C++的其他内存管理接口(placeman版本)

    void * operator new (size_t size);
    void operator delete (size_t size);
    void * operator new [](size_t size);
    void operator delete[] (size_t size);
    

    new表达式与operator new函数
    标准库函数operator new和operator delete的命名容易让人误解。与其他operator函数(如 operator=)不同,这些函数没有重载new或delete表达式,实际上,我们不能重定义new和delete表达式的行为。
    通过operator new函数执行new表达式获得内存,并接着在该内存中构造一个对象,通过撤销一个对象执行delete表达式,并接着调用operator delete函数,以释放该对象使用的内存。

总结:
1. operator new/operator delete、operator new[]/operator delete[]和malloc/free用法一样。
2. 他们只负责分配空间/释放空间,不会调用对象的构造函数/析构函数来初始化对象/清理对象。
3. 实际operator new和operator delete只是malloc和free的一层封装

  • new做了两件事
    1. 调用operator new分配空间。
    2. 调用构造函数初始化对象。
  • delete也做了两件事

    1. 调用析构函数清理对象
    2. 调用operator delete释放空间
  • new[N]

    1. 调用operator new分配空间
    2. 调用N次构造函数分别初始化每个对象
  • delete[]
    1.调用N次析构函数清理对象
    1. 调用operator delete释放空间
  • 定位new表达式(replacement版本)
    定位new表达式是在已分配的原始内存空间中调用构造函数初始化一个对象
    new(place_address)type
    new(place_address) type(initializer-list)
    place_address必须是一个指针,initializer-list是类型的初始化列表
class Array
{
public :
Array (size_t size = 10)
: _size(size )
, _a(0)
{
cout<<"Array(size_t size)" <<endl;
if (_size > 0)
{
_a = new int[ size];
}
}
~ Array()
{
cout<<"~Array()" <<endl;
if (_a )
{
delete[] _a ;
_a = 0;
_size = 0;
}
}
private :
int* _a ;
size_t _size ;
};
void Test ()
{
// 1.malloc/free + 定位操作符new()/显示调用析构函数,模拟 new和delete 的行为
Array* p1 = (Array*) malloc(sizeof (Array));
new(p1 ) Array(100);
p1->~Array ();
free(p1 );
// 1.malloc/free + 多次调用定位操作符new()/显示调用析构函数,模拟 new[]和delete[] 的行为
Array* p2 = (Array*) malloc(sizeof (Array)*10);
for(int i = 0; i < 10; ++i )
{
new(p2 +i) Array;
}
for(int i = 0; i < 10; ++i )
{
p2[i ].~Array();
}
free(p2 );
}

这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值