C++入门之内存管理|复习C中的malloc,realloc,calloc|内存分布|内存管理|new delete|operator new|operator delete

目录

一、C/C++内存分布

1.C/C++中程序内存区域划分

二、C语言中动态内存管理

1.malloc/calloc/realloc/free

三、C++中动态内存管理

1.new/delete操作内置类型

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

四、operator new与operator delete函数

1.operator new和operator delete函数

五、new和delete的实现原理

1.内置类型

2.自定义类型

malloc/free和new/delete的区别

总结


一、C/C++内存分布

1.C/C++中程序内存区域划分

在内存中,内存被划分为不同的区域,便于os管理,主要分为以下几个部分:

  • 内核空间(用户代码不能读写)
  • (向下增长):又称为堆栈,存储非静态的局部变量,函数参数,返回值等。
  • 内存映射段:是高效的IO映射方式,用于装载一个共享的动态内存库,用户可以使用系统接口创建共享内存,用于进程间通信
  • (向上增长):用于程序运行时的动态内存分配。mallo/realloc...出来的值在堆上
  • 数据段(又称为静态区):存储全局变量和静态变量
  • 代码段(常量区):存放可执行的代码/只读常量

 char2在哪里?局部变量 在栈上      

* char2 在哪里?数组名为首元素地址,char2指向a的地址, *char2指向a,在栈上
 pChar3 在哪里? 局部变量 在栈上     
* pChar3 在哪里?指向一个字符常量,在代码段(常量区)
 ptr1 在哪里?  局部变量,在栈上
* ptr1 在哪里? 指向mallo出来的值,在堆上

二、C语言中动态内存管理

1.malloc/calloc/realloc/free

void Test ()
{
int* p1 = (int*) malloc(sizeof(int));
free(p1);
// 1.malloc/calloc/realloc的区别是什么?
int* p2 = (int*)calloc(4, sizeof (int));
int* p3 = (int*)realloc(p2, sizeof(int)*10);
// 这里需要free(p2)吗?  不需要
free(p3 );
}
  • malloc:开辟size个字节的内存,开辟成功返回这块内存的起始地址,如果失败返回一个空指针,返回的起始地址为void * 类型

  •  calloc:开辟num*类型个字节的地址,并且初始化为0,如果size为0,返回值取决于特定的库(不确定是否为空指针),但是返回的指针不能被解引用。如果开辟成功,返回起始地址,类型为void*,开辟失败,返回空指针

 

  • realloc :改变ptr指向内存块的大小,函数将内存块移动到一个新的位置,保留原来两个大小中较小的一个,如果ptr是空指针,作用和malloc相同。

三、C++中动态内存管理

1.new/delete操作内置类型

void Test()
{
  // 动态申请一个int类型的空间
  int* ptr4 = new int;
  
  // 动态申请一个int类型的空间并初始化为10
  int* ptr5 = new int(10);
  
  // 动态申请10个int类型的空间
  int* ptr6 = new int[10];
  delete ptr4;
  delete ptr5;
  delete[] ptr6;
}

申请和释放单个元素的空间,使用new和delete操作符,申请和释放连续的空间,使用new[]和delete[]。注意操作符要匹配使用

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

class A
{
public:
  //构造
 A(int a = 0)
 : _a(a)
 {
     cout << "A():" << this << endl;
  }

//注:在申请自定义类型的空间时,new会调用构造函数,delete会调用析构函数,而malloc与
free不会。

 ~A()
 {
 cout << "~A():" << this << endl;
 }
private:
 int _a;
};
int main()
{
 // new/delete 和 malloc/free最大区别是 new/delete对于【自定义类型】除了开空间
还会调用构造函数和析构函数
 A* p1 = (A*)malloc(sizeof(A));
 A* p2 = new A(1);
 free(p1);
 delete p2;
 // 内置类型是几乎是一样的
 int* p3 = (int*)malloc(sizeof(int)); // C
 int* p4 = new int;
free(p3);
delete p4;
 A* p5 = (A*)malloc(sizeof(A)*10);
 A* p6 = new A[10];
 free(p5);
 delete[] p6;
 return 0;
}

四、operator new与operator delete函数

1.operator new和operator delete函数

new delete 是用户进行 动态内存申请和释放的操作符 operator new operator delete
系统提供的 全局函数 new 在底层调用 operator new 全局函数来申请空间, delete 在底层通过 operator delete 全局函数来释放空间。
operator new 实际也是通过 malloc 来申请空间 ,如果malloc 申请空间成功就直接返回,否则执行用户提供的空间不足应对措施,如果用户提供该措施 就继续申请,否则就抛异常。 operator delete 最终是通过 free 来释放空间的

五、new和delete的实现原理

1.内置类型

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

2.自定义类型

  • new的原理

    1.调用operator new申请空间

    2.在申请的空间上执行构造函数,完成对象的构造

  • delete原理

    1.在空间上执行析构函数,完成对象中资源的清理工作

    2.调用operator delete函数释放对象的空间

  •     new T[N] 的原理
    1. 调用 operator new[] 函数,在 operator new[] 中实际调用 operator new 函数完成 N 个对 象空间的申请
    2. 在申请的空间上执行 N 次构造函数
  • delete[]的原理
   1. 在释放的对象空间上执行 N 次析构函数,完成 N 个对象中资源的清理
   2. 调用 operator delete[] 释放空间,实际在 operator delete[] 中调用 operator delete 来释
放空间

malloc/free和new/delete的区别

malloc/free和new/delete的共同点:都从堆上申请空间,并且需要用户手动释放。不同的地方从以下两个方面回答:用法和底层原理上

1.用法

  • 1. mallocfree是函数,newdelete是操作符
  • 2. malloc申请的空间不会初始化,new可以初始化
  • 3. malloc申请空间时,需要手动计算空间大小并传递,new只需在其后跟上空间的类型即可, 如果是多个对象,[]中指定对象个数即可
  • 4. malloc的返回值为void*, 在使用时必须强转,new不需要,因为new后跟的是空间的类型

2.底层原理

  • malloc申请空间失败时,返回的是NULL,因此使用时必须判空,new不需要,但是new
要捕获异常
  •  申请自定义类型对象时,malloc/free只会开辟空间,不会调用构造函数与析构函数,而new 在申请空间后会调用构造函数完成对象的初始化,delete在释放空间前会调用析构函数完成 空间中资源的清理

总结

本章主要总结了关于C/C++中内存分布,以及malloc,realloc,calloc函数,还有new/delete操作符的用法

猜你喜欢

转载自blog.csdn.net/jolly0514/article/details/131740626