1、C/C++内存模型
1. 栈:栈⽤于存储函数的局部变量、函数参数和函数调⽤信息的区域。函数的调⽤和返回通过栈来管理。向下增长。2. 堆:堆⽤于存储动态分配的内存的区域,由程序员⼿动分配和释放。使⽤ new 和 delete 或 malloc 和 free 来进⾏堆内存的分配和释放。向上增长。3. 全局/静态区: 全局区存储全局变量和静态变量。⽣命周期是整个程序运⾏期间。在程序启动时分配,程序结束时释放。4. 常量区: 常量区也被称为只读区。存储常量数据,如字符串常量。5. 代码区:存储程序的代码。
2、编译的四个过程
1、预处理:引入头文件,宏替换,删除注释…生成以.i为结尾的预编译文件
2、编译:检查语义语法规错误,无错误则生成以.s为结尾的汇编文件
3、汇编:将汇编代码解释为二进制的cpu指令,生成.o为结尾的可重定向目标文件
4、链接: 将多个目标文件及所需要的库连接成最终的可执行目标文件
什么是extern"C"?
可以在 C++中使用C 的已编译好的函数模块,这时候就需要用到 extern”C” 。也就是 extern“C” 都是在c++ 文件里添加的。extern 在链接阶段起作用(四大阶段:预处理 -- 编译 -- 汇编 -- 链接)。
3、c++11的新特性
找出了比较简单的几条:
- 1、用auto关键字来支持自动类型推导
- 2、引入了范围for循环,提供了一种简洁而直观的方式来遍历容器、数组、字符串和其他可迭代对象。比如for(char c : str){..}。
- 3、引入了新的智能指针类(独占式、共享式、弱引用),用于更安全和方便地管理动态分配的资源,避免内存泄漏和悬空指针等问题。
- 4、统一初始化:直接初始化、拷贝初始化、列表初始化
- 5、nullptr是c++11用来表示空指针新引入的常量值,在c++中如果表示空指针语义时建议使用nullptr而不要使用NULL,因为NULL本质上是个int型的0,其实不是个指针
- 6、lambda匿名函数
- 7、右值引用
- 8、原子操作
4、malloc/free和new/delete的区别
- malloc和free是函数(C/C++),new和delete是操作符(C++)。
new
和delete
在 C++ 中提供了更高级、更类型安全的内存管理功能。- 申请空间:使用new操作符申请内存分配时无须指定内存块的大小,编译器会根据类型信息自行计算。而malloc则需要显式地指出所需内存的尺寸。
- 类型强转与否:malloc的返回值为void*, 在使用时必须强转;而new后跟的是空间的类型,就不需要强转。说明:new操作符内存分配成功时,返回的是对象类型的指针,类型严格与对象匹配,无须进行类型转换,故new是符合类型安全性的操作符。而malloc内存分配成功则是返回void * ,需要通过强制类型转换将void*指针转换成我们需要的类型。
- 申请空间失败时:malloc返回的是NULL;而new会抛异常。
- 申请自定义类型对象时:malloc/free只会开辟空间,不会调用构造函数与析构函数,而new会调用构造函数完成对象的初始化,delete在释放空间前会调用析构函数完成空间中资源的清理。
在1G内存的计算机中能否malloc(1.2G)?为什么?
是有可能申请 1.2G 的内存的。应用程序通过 malloc 函数可以向程序的虚拟空间申请一块虚拟地址空间,与物理内存没有直接关系,得到的是在虚拟地址空间中的地址,之后程序运行所提供的物理内存是由操作系统完成的。
什么是虚拟内存?
虚拟内存是一种计算机系统内存管理技术,它为应用程序提供了一个连续可用的内存空间,但实际上,这部分内存可能分布在物理内存的不同碎片中,甚至部分暂时存储在外部磁盘存储器上。
5、什么是内存泄漏,怎么避免?
内存泄漏:程序未能释放掉不再使用的内存
- 养成良好的编码规范,申请的内存空间记着匹配的去释放内存
- 使用内存泄漏工具检测(在linux环境下可以使用内存泄漏检测工具Valgrind,我们写代码是可以添加内存