网站开发要学多久,正定县建设局网站,厦门市建设执业资格注册管理中心网站,卢松松wordpress模板一、C/C内存分布
C/C内存被分为6个区域#xff1a; #xff08;1#xff09; 内核空间#xff1a;存放内核代码和环境变量。
#xff08;2#xff09;栈区#xff1a;向下增长#xff08;存放非静态局部变量#xff0c;函数参数#xff0c;返回值等等#xff09; …
一、C/C内存分布
C/C内存被分为6个区域 1 内核空间存放内核代码和环境变量。
2栈区向下增长存放非静态局部变量函数参数返回值等等
3内存映射段文件映射匿名映射动态库。
4堆区向上增长用于程序运行时动态内存的分配
5数据段也叫静态区/全局域存放全局变量和静态变量
6代码段也叫常量区存放可读代码和只读常量 看看下面代码的例题
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);
}选择题 选项: A.栈 B.堆 C.数据段(静态区) D.代码段(常量区) globalVar在哪里____ staticGlobalVar在哪里____ staticVar在哪里____ localVar在哪里____ num1 在哪里____ char2在哪里____ *char2在哪里___ pChar3在哪里____ *pChar3在哪里____ ptr1在哪里____ *ptr1在哪里____ 填空题 sizeof(num1) ____; sizeof(char2) ____; strlen(char2) ____; sizeof(pChar3) ____; strlen(pChar3) ____; sizeof(ptr1) ____; sizeof 和 strlen 区别 1.C C C A A 2. A A A D A B 3.40 5 4 4或8 4 4或8 3.sizeof和strlen的区别 1char ch2[ ]“abcd”; // sizeof(ch2)5 因为末尾还有一个’\0’ // strlen(ch2)4 因为strlen其他都不管遇到’\0’就结束‘\0’不计入 2sizeof内部要看变量是否为指针若是指针4/8 strlen不看变量是否为指针只看’\0’ 遇到’\0’结束为止
4.对char2pchar3ptr1的解释 1字符串存在于常量区当拿来初始化char2的时候char2会在栈区开辟一个空间然后再把字符串拷贝给char2char2就在栈区。
2char2是数组名对地址解引用*char2仍然在栈区
3 被const的修饰变量不一定在常量区有可能const修饰的是常变量存放在栈区
4pchar3是在栈上的指针变量*pchar3‘abcd\0’是指向的字符串“abcd\0”存放在常量区
5ptr1是在栈上的指针变量ptr1由于是由malloc出来的所以ptr1指向的空间即*ptr1在堆区 二、C/C使用new和delete的原因
new和delete是C向内存申请空间和释放空间的操作符 C为什么要使用new和delete
1.C语言使用malloc、calloc、realloc、free管理的不便之处在于
1需要手动申请空间手动计算申请的字节大小。
2对返回值void*需要进行强转否则无法进行解引用。
3内存申请是否成功还需要进行判断。
4需要include头文件stdlib.h
2.new和delete对自定义类型也会进行处理
1new会调用构造函数对类对象进行初始化
2delete会调用析构函数进行资源清理
三、C动态管理内存的方式
1.new和delete
1new/delete和malloc/free对内置类型的操作没有区别 注意 ①申请和释放单个空间需要用new和delete。 ②申请和释放多个空间需要用new [ ]和delete [ ]
2new的特点
#define _CRT_SECURE_NO_WARNINGS 1
#include stdio.h
#include stdlib.h
#include iostream
using namespace std;int main()
{// 1.C语言申请空间int* p0 (int*)malloc(sizeof(int) * 4);if (p0 NULL){perror(malloc fail);return 1;}free(p0);// 2.new 1个int整型的元素int* p1 new int;delete p1;// 3.new 10个int整型元素(即数组)int* p2 new int[10];// 申请的时候为new[ ] ,释放的时候必须要用delete[ ] delete[] p2;// 4.可以控制初始化int* p3 new int(10); // new一个int整型 并且初始化为10delete p3;// 5.new失败后会抛异常不必手动检查
}C11开始支持new初始化数组 如果没有初始化到的默认为0
int* p4 new int[10] {1, 2, 3, 4, 5};
delete[] p4;3new/delete和malloc/free对自定义类型的操作有区别
①malloc/free对自定义类型的操作只会开空间/释放空间
②new操作自定义类型会开空间构造函数初始化delete操作自定义类型会调用析构函数清理释放空间
class ListNode
{
public:ListNode* _prev;ListNode* _next;int _val ;ListNode():_prev(nullptr),_next(nullptr),_val(0){cout this _val _val endl;}~ListNode(){cout ~ListNode() endl;}
};int main()
{ListNode* p1 (ListNode*)malloc(sizeof(ListNode) * 4);ListNode* p2 new ListNode;free(p1);delete(p2);return 0;
}当程序走完第94行之后那么p2里面的值都被初始化了。然而对于93行malloc出来的值都是随机值。从调试的界面可以看出它也调用了构造函数所以打印出:this _val0 这就是new和malloc的区别new对自定义类型会调用构造函数delete会调用析构函数对对象进行初始化和空间清理而C语言之前的malloc和free不会这样做他们只会开辟空间和释放空间。 2.operator new和operator delete
1定义operator new 和operator delete是系统提供的全局函数new在底层调用operator new全局函数来申请空间operator new是对malloc的封装delete在底层通过operator delete全局函数来释放空间operator delete是对free的封装它们不是new和delete的重载。 2与malloc区别operator new、operator delete的用法和malloc、free的用法是一样的功能都是在堆上申请释放空间但是失败了的处理方式不一样malloc失败返回NULLoperator new失败以后抛异常。 使用new为自定义类型ListNode申请空间并初始化new会调用operator new函数和构造函数operator new会调用malloc和失败抛异常机制因此new和operator new申请失败都会抛异常 从上图可以看出new并不直接调用 malloc而是调用了operator new因为operator new被封装了malloc申请失败直接报返回值但operator new申请失败会抛异常 总结 对于自定义类型来说只有自定义类型才有构造和析构内置类型不存在的 1new—operator new—malloc构造函数 2delete—析构函数operator delete—free 注意两者的顺序不同
3.总结
malloc/free和new/delete总结 1malloc/free是函数new/delete是操作符
2malloc申请的空间不会初始化new可以初始化
3malloc申请的空间需要手动计算并传递过去而new只需要在后面跟上空间类型即可。
4new不需要强转而malloc需要
5malloc申请空间之后需要判断是否申请失败new不需要但是new需要捕获异常
6申请自定义类型对象时malloc/free只会开辟空间而new在申请空间 后会调用构造函数完成对象的初始化delete在释放空间 前 会调用析构函数完成空间中资源的清理。
五、内存泄漏
1.定义内存泄漏的概念一块已经不用的空间没有释放
2.危害长期运行的程序出现内存泄漏影响很大如操作系统、后台服务等等出现内存泄漏会 导致响应越来越慢最终卡死。
3.有关内存泄漏的例题
class A
{
public:A(){cout A() endl;}~A(){cout ~A() endl;}
};int main()
{A* a new A[5];//delete a; 内存泄漏只释放了1次delete[] a;return 0;
}关键点记住一定要匹配使用如若违背结果将不确定
new—delete new[ ] —delete[ ] 好了今天的分享就到这里了 如果对你有帮助记得点赞关注哦 我的主页还有其他文章欢迎学习指点。关注我让我们一起学习一起成长吧