比特币网站建设,php网站建设考试,全包装修公司哪家好点,吉林省网站建设公司目录
1. 一图搞懂C/C的内存分布
2. 存在动态内存分配的原因
3. C语言中的动态内存管理方式
4. C内存管理方式
4.1 new/delete操作内置类型
4.2 new/delete操作自定义类型 1. 一图搞懂C/C的内存分布 说明#xff1a; 1. 栈区#xff08;stack#xff09;#xff1a;在…目录
1. 一图搞懂C/C的内存分布
2. 存在动态内存分配的原因
3. C语言中的动态内存管理方式
4. C内存管理方式
4.1 new/delete操作内置类型
4.2 new/delete操作自定义类型 1. 一图搞懂C/C的内存分布 说明 1. 栈区stack在执行函数时函数内局部变量的存储单元都可以在栈上创建函数执行结 束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中效率很高但是 分配的内存容量有限。 栈区主要存放运行函数而分配的局部变量、函数参数、返回数据、返回地址等。 2. 堆区heap一般由程序员分配释放 若程序员不释放程序结束时可能由OS回收 。分配方式类似于链表。 3. 数据段静态区static存放全局变量、静态数据。程序结束后由系统释放。 4. 代码区存放函数体类成员函数和全局函数的二进制代码。 2. 存在动态内存分配的原因
现在我们最朗朗上手的内存开辟方式有 int a 10;//在栈空间上开辟4个字节的空间int arr[100] { 0 };//在栈空间上开辟100×4个字节的空间
上述两种方法开辟空间的方式有两个特点 1. 空间开辟大小是固定的 2. 数组在申明的时候必须指定数组的长度它所需要的内存在编译时分配。 但是对于空间的需求不仅仅是上述的情况。有时我们需要的空间大小在程序运行时才能知道。
其如果比我们开辟的空间大程序会不会报错呢如果比我们开辟的空间小那又会不会造成内存浪费降低运行效率呢
所以这种静态的内存开辟方式就不能满足我们的需求了那该如何来解决呢
这时动态的内存开辟或许就可以满足我们的需求。
3. C语言中的动态内存管理方式
C语言中的动态内存管理方式为malloc、calloc、realloc、free函数的使用具体请看详解C/C动态内存函数malloc、free、calloc、realloc
4. C内存管理方式 我们说过C是兼容C语言的所以C语言的内存管理方式在C中可以继续使用但有些地方就无能为力而且使用起来比较麻烦因此C又提出了自己的内存管理方式通过new和delete操作符进行动态内存管理。 了解C的类与对象之后我们知道了内置类型和自定义类型我们似乎可以发现在学习了C的很多知识后好像很大一部分篇幅都在介绍处理自定义类型的情况这些也恰巧可以体现C面向对象的原因所以对于new和delete我们也应该分为内置类型与自定义类型来讨论。 4.1 new/delete操作内置类型
new/delete操作内置类型与malloc、calloc、realloc、free函数除了用法上其他方面没有任何区别用法也完全可以照猫画虎不过确实new/delete更为方便
void test()
{// ①动态申请一个int类型的空间//malloc//int* ptr1 (int*)malloc(sizeof(int));//newint* ptr1 new int;// ②动态申请一个int类型的空间并初始化为10//malloc/*int* ptr2 (int*)malloc(sizeof(int));if (ptr2 NULL){perror(malloc);exit(-1);}*ptr2 10;*///newint* ptr2 new int(10);//③ 动态申请10个int类型的空间//calloc/*int* ptr3 (int*)calloc(10, sizeof(int));if (ptr3 NULL){perror(calloc);exit(-1);}*///newint* ptr3 new int[10];//④动态申请10个int类型的空间并初始化成1~10//直接演示new:int* ptr4 new int[10]{ 1,2,3,4,5,6,7,8,9,10 };//(如果未初始化完全其余默认初始化为0)//free/*free(ptr1);ptr1 NULL;*///deletedelete ptr1;delete ptr2;delete[] ptr3;delete[] ptr4;
}
注意申请和释放单个元素的空间使用new和delete操作符申请和释放连续的空间使用 new[]和delete[]要匹配起来使用。 4.2 new/delete操作自定义类型
我们已经说了new/delete与malloc、calloc、realloc、free除了用法上其他方面没有区别那既然已经有了后者为什么还要再引入new/delete呢仅仅是为了用法上更方便一些吗
答案当然不是的没有任何区别仅仅是针对内置类型来说的我们在学习操作符重载时就发现、-、*、/ 这些运算符对于自定义类型并不能直接拿来用需要加以重载我们才可以使用。
malloc、calloc、realloc、free这些函数也是同样的道理所以针对自定义类型new与delete就应运而生了。
那么我们就跟着new/delete操作内置类型的用法照猫画虎来试一下自定义类型A:
#include iostream
using namespace std;class A
{
public://构造函数A(int a 0):_a(a){cout 调用了构造函数 this endl;}//析构函数~A(){cout 调用了析构函数 this endl;}private:int _a;
};int main()
{//动态申请1个A类型的空间并初始化为1A* a1 new A(1);delete a1;return 0;
}
运行结果 从运行结果来看 new/delete 和 malloc/free最大区别是 new/delete对于【自定义类型】除了开空间还会调用构造函数和析构函数。 所以我们可以说 new的本质开空间调用构造函数初始化 delete的本质调用析构函数释放空间。 另外熟悉一下用new对自定义类型开多个空间
int main()
{//动态申请3个A类型的空间并初始化为1~3//方法①有名对象/*A a1(1);A a2(2);A a3(3);A* aa1 new A[3]{ a1,a2,a3 };delete[] aa1;*///方法②匿名对象A* aa2 new A[3]{ A(1),A(2),A(3) };delete[] aa2;//方法③巧用构造函数的隐式类型转换A* aa3 new A[3]{ 1,2,3 };delete[] aa3;return 0;
}
本篇完