C++/C-----内存管理

本文详细解析了C/C++中的内存分布,包括栈、数据段、代码段、堆和内存映射区。讲解了如何判断内存区,并介绍了C/C++的内存管理方法,如malloc、realloc、calloc、free以及new、delete的区别和使用。还讨论了new表达式的定位和构造函数/析构函数的应用。
摘要由CSDN通过智能技术生成

一.C/C++内存分布

1. 具体分布

(1)栈

函数栈帧的开辟,非静态局部变量/返回值/函数参数,它的特点是栈是向下增长

(2)数据段(静态区)

全局数据,static修饰的变量

(3)代码段(常量区)

存放常量例如字符串,可执行代码

(4)堆

用来动态申请内存的。它是向上增长的

(5)内存映射区

 内存映射段是高效的I/O映射方式,用于装载一个共享的动态内存库。用户可使用系统接口 创建共享共享内存,做进程间通信

(6)内核空间

 2.常见的内存区的判断


int globalVar = 1;
static int staticGlobalVar = 1;
void Test()
{
 static int staticVar = 1;
 int localVar = 1;
 int num1[10] = { 1, 2, 3, 4 };
 char char2[] = "abcd";
 const char* pChar3 = "abcd";
 int* ptr1 = (int*)malloc(sizeof(int) * 4);
 int* ptr2 = (int*)calloc(4, sizeof(int));
 int* ptr3 = (int*)realloc(ptr2, sizeof(int) * 4);
 free(ptr1);
 free(ptr3);
}
1. 
   选项: A.栈  B.堆  C.数据段(静态区)  D.代码段(常量区)
   globalVar在哪里?__数据段__   staticGlobalVar在哪里?__数据段__
   staticVar在哪里?__数据段__   localVar在哪里?__栈__
   num1 在哪里?___栈_
  
   char2在哪里?__栈__   *char2在哪里?_栈__
   pChar3在哪里?_栈___      *pChar3在哪里?__代码段__
   ptr1在哪里?__栈__        *ptr1在哪里?___堆_
2. 填空题:
   sizeof(num1) = __40_;  

   sizeof(char2) = ___5;      strlen(char2) = _4_;(不包括'/0')
   sizeof(pChar3) = __8/4__;     strlen(pChar3) = _4_;(不包括'/0')
   sizeof(ptr1) = __8/4__;
3. sizeof 和 strlen 区别
   1.sizeof 是操作符,不是函数,根据类型计算的内存大小,它可以计算对象,结构体等,
   2.strlen 是计算字符串长度的函数,遇到‘/0’结束,返回字符串的长度(不包括‘/0’),而sizeof在计算字符串内存大小包括‘/0’.

二.C语言的内存管理方式

1.malloc/realloc/calloc/free

(1)malloc

用来动态开辟内存,以字节为单位,如果开辟失败,返回空指针(NULL)

(2)realloc

如果我们开辟的空间不够,可以使用realloc来扩容,如果realloc第一个参数为空,可以理解为和malloc作用相同。

(3)calloc

开辟空间的同时,会初始化为0

void Test ()
{
int* p1 = (int*) malloc(sizeof(int));
free(p1);
int* p2 = (int*)calloc(4, sizeof (int));
int* p3 = (int*)realloc(p2, sizeof(int)*10);
// 这里需要free(p2)吗?realloc在进行扩容的时候,它自己会释放掉原来的空间,不需要我们手动free
free(p3 );
}

三.C++内存管理方式

C++是面对对象,而C语言没有对象这个概念。如果沿用C语言方式来开辟对象的空间,这又涉及到对象的初始化问题,我们知道类实例化的时候,编译器会自动调用构造函数进行初始化,所以有了new和delete。

/new/delete 和 malloc/free最大区别是 new/delete对于【自定义类型】除了开空间 还会调用构造函数和析构函数

1.new 和delet

(1)自定义类型和内置类型

	//内置类型
	int *pyt=new int(3);//申请一个int大小,初始化为3
	int* ptr2 = new int[3] {1, 2, 3};//连续申请3个int,分别初始化
	delete pyt;
	delete []ptr2;//释放连续的空间配合[]

	//自定义类型
	MyQL* ptr3 = new MyQL(1);//申请一个对象(MyQL)空间同时调用构造函数
	delete ptr3;
	MyQL* ptr4 = new MyQL[3]{ 1,2,3 };//连续申请3个对象空间,调用3次构造函数(1,2,3会隐式转换)
	delete []ptr4;//释放连续空间,调用析构函数完成对象资源清理,然后在释放对象的空间
void Test()
{
  // 动态申请一个int类型的空间
  int* ptr4 = new int;
  
  // 动态申请一个int类型的空间并初始化为10
  int* ptr5 = new int(10);
  
  // 动态申请10个int类型的空间
  int* ptr6 = new int[3];
  delete ptr4;
  delete ptr5;
  delete[] ptr6;
}

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

(2)new和delete的底层实现原理

new和delete是操作符,实际调用的是两个全局函数

new和delete是用户进行动态内存申请和释放的操作符,operator new 和operator delete是 系统提供的全局函数,new在底层调用operator new全局函数来申请空间,delete在底层通过 operator delete全局函数来释放空间。实际上申请空间的是malloc函数,释放使用的是free函数。可以理解为new和delete是malloc和free的封装。

operator new[]----->operator new------>malloc

 operator delete[]----->operator delete------>free

(3)delete/new和malloc/free区别

1.malloc/free是函数,delete/free是操作符

2.malloc申请的空间要计算申请空间的大小,而new只需要类型,如果申请多个对象只需在[]说明个数

3.mallo申请空间不会初始化,new会初始化

4.malloc的返回值为void*, 在使用时必须强转,new不需要,因为new后跟的是空间的类型

5.malloc如果申请失败返回空指针,new失败抛出异常

6.申请自定义类型对象时,malloc/free只会开辟空间,不会调用构造函数与析构函数,而new 在申请空间后会调用构造函数完成对象的初始化,delete在释放空间前会调用析构函数完成 空间中资源的清理

四.定位new表达式

new (place_address) type或者new (place_address) type(initializer-list) place_address必须是一个指针,initializer-list是类型的初始化列表

1.定位new表达式可以通过它显示调用构造函数

如果我们申请了对象的空间但是又没有初始化它,那么我们就可以通过定位new表达式,完成初始化工作,它最大的用处是内存池的对象的初始化

class MyQL {
public:
	MyQL(int n)
		:next(nullptr)
		,date(n)
	{
		
	}
private:
	MyQL* next;
	int date;


};
int main()
{

MyQL* ptr = (MyQL*)malloc(sizeof(MyQL));
//不可以这样ptr->MyQL(1)
new(ptr)MyQL(1);
	return 0;
	                                                                                                                                         


}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值