程序员成长之旅——C/C++内存管理上篇

C/C++内存分布

先看一个代码段的题

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";
	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在哪里?__C__ staticGlobalVar在哪里?_C___
	staticVar在哪里?_C___ localVar在哪里?__A__
	num1 在哪里?_A___
	char2在哪里?__A__ * char2在哪里?A___
	pChar3在哪里?_A___ * pChar3在哪里?__D__
	ptr1在哪里?_A___ * ptr1在哪里?__B__
2. 填空题:
sizeof(num1) = __40__;
sizeof(char2) = __5__; strlen(char2) = __4__;
sizeof(pChar3) = _4___; strlen(pChar3) = _4___;
sizeof(ptr1) = __4__;

上面这个题要注意 * char2 和 * pChar3存放的区别
char2 是数组首元素地址,解引用的话就是将数组第一个元素(刚开始的话就是将常量区的数字带到数组中并初始化)所以也是在栈上。
pchar3是字符串首元素地址,解引用就是字符串首元素,而字符串在常量区,也就是代码段。

再根据一个图片了解一下
在这里插入图片描述
说明

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

C语言中动态内存管理方式

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/calloc/realloc的区别

C++中内存管理方式

C语言内存管理方式在C++中可以继续使用,但有些地方就无能为力而且使用起来比较麻烦,因此C++又提出了自己的内存管理方式:通过new和delete操作符进行动态内存管理。

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操作自定义类型

class Test
{
public:
  Test()
  	: _data(0)
  {
  	cout << "Test():" << this << endl;
  }
  ~Test()
  {
  	cout << "~Test():" << this << endl;
  }
private:
  int _data;
};
void Test2()
{
  // 申请单个Test类型的空间
  Test* p1 = (Test*)malloc(sizeof(Test));
  free(p1);
  // 申请10个Test类型的空间
  Test* p2 = (Test*)malloc(sizeof(Test) * 10);
  free(p2);
}
void Test2()
{
  // 申请单个Test类型的对象
  Test* p1 = new Test;
  delete p1;
  // 申请10个Test类型的对象
  Test* p2 = new Test[10];
  delete[] p2;
}

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

operator new 和 operator delete

new和delete是用户进行动态内存申请和释放的操作符,operator new 和operator delete是系统提供的全局函数,new在底层调用operator new全局函数来申请空间,delete在底层通过operator delete全局函数来释放空间。

#include<iostream>
using namespace std;
class Test
{
public:
	Test()
	{
		cout << "Test()" << endl;
	}
	~Test()
	{
		cout << "~Test():" << this << endl;
	}
private:
	int _data;
};
int main()
{
	Test* pt = new Test;
	new: 这是一个关键字
	/*1.申请空间----->void* operator new(字节数)
	循环使用malloc(size)申请空间
	成功直接返回  失败空间不足 空间不足的应对措施(函数)  ---  用户
	2.调用构造函数*/
	delete pt;
	delete
	/*1.先调用析构函数:释放对象中的资源
	2.释放空间void operator delete(void*)--->free*/
	Test* pt = new Test[10];
	delete[] pt;
	return 0;
}

operator new 这是一个函数
malloc申请空间
1.成功—>直接返回
2.失败—>执行用户提供的空间不足的应对措施:
----------a.用户未提供—抛异常
----------b.用户提供—执行—继续用malloc申请—到1循环下去—直到申请成功
new T[N]
1.申请空间 void* operator new—>void* operator new(字节数)—>malloc
2.调用N次构造函数

operator malloc 是通过malloc来申请空间的,如果malloc申请空间成功就直接返回,否则执行用户提供的空间不足应对措施,如果用户提供该措施就继续申请,否则就抛异常。operator delete 最终是通过free来释放空间的。

new 和 delete 实现原理

内置类型

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

自定义类型
  • 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来释放空间
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

从零出发——

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值