C++面试高频(内存)
内存
1 内存分配的方式⭐⭐⭐⭐⭐
在编程中,内存分配方式主要有三种,分别是静态内存分配、栈内存分配和堆内存分配,下面为你详细介绍:
静态内存分配
- 分配时机:在程序编译阶段就完成内存分配,编译器会根据程序中定义的静态变量和全局变量,确定它们所需的内存空间,并在可执行文件中预留相应的内存区域。
- 作用域与生命周期:静态变量和全局变量的作用域和生命周期取决于它们的定义方式。全局变量在整个程序的生命周期内都存在,可在程序的任何地方访问;静态变量的作用域根据其定义位置而定,但其生命周期同样是整个程序运行期间。
- 使用场景:适用于那些在程序运行过程中不需要动态调整大小,且需要在整个程序生命周期内保持存在的数据,如程序中的常量、配置信息等。
- 优点:由于在编译时就确定了内存分配,因此分配速度快,不需要在运行时进行额外的内存管理操作。
- 缺点:缺乏灵活性,一旦程序编译完成,静态变量和全局变量的内存大小就不能再改变。
栈内存分配
- 分配时机:在程序运行过程中,当函数被调用时,系统会在栈上为该函数的局部变量、参数和返回地址等分配内存空间。当函数执行结束后,这些内存空间会自动被释放。
- 作用域与生命周期:栈上分配的变量的作用域通常是定义它们的函数内部,其生命周期从变量定义开始,到函数执行结束为止。
- 使用场景:适用于存储函数内部的临时变量和局部数据,这些数据的生命周期较短,且不需要在函数调用结束后继续存在。
- 优点:栈内存的分配和释放速度非常快,因为它只需要移动栈指针即可完成操作。此外,栈内存的管理由系统自动完成,程序员无需手动干预,减少了内存泄漏的风险。
- 缺点:栈的空间通常比较有限,如果在函数中分配了大量的局部变量,可能会导致栈溢出错误。
堆内存分配
- 分配时机:在程序运行时,通过特定的函数(如 C 语言中的
malloc
、calloc
、realloc
,C++ 中的new
)来动态地申请内存空间。程序员可以根据程序的需要,在合适的时机分配和释放内存。 - 作用域与生命周期:堆上分配的内存的生命周期由程序员手动控制,即通过调用相应的释放函数(如 C 语言中的
free
,C++ 中的delete
、delete[]
)来释放内存。如果程序员忘记释放内存,就会导致内存泄漏。 - 使用场景:适用于需要动态调整大小的数据结构,如数组、链表、树等,以及在程序运行过程中需要根据用户输入或其他条件来分配内存的情况。
- 优点:堆内存的空间相对较大,且可以根据程序的需要动态地分配和释放,具有很高的灵活性。
- 缺点:堆内存的分配和释放速度相对较慢,因为需要进行复杂的内存管理操作。此外,手动管理堆内存容易出现内存泄漏和悬空指针等问题,增加了程序的复杂性和出错的风险。
2 堆和栈的区别⭐⭐⭐⭐⭐
1 申请方式
栈的空间由操作系统自动分配/释放,堆上的空间手动分配/释放。
2 申请大小的限制
栈空间有限,栈是向低地址拓展的数据结构,是一块连续的内存区域。
堆有很大的自由存储区。堆是向高地址拓展的数据结构,是不连续的内存区域。
3 申请效率
栈是由系统自动分配的,速度比较快。但程序员是无法控制的。
堆是由new分配的的内存,一般速度比较慢,而且容易产生内存碎片。用起来很方便。
3 栈在C++中的作用⭐⭐⭐⭐⭐
1 c++中栈是用来存储临时变量,临时变量包括函数参数和函数内部定义的临时变量。函数中调用中函数调用相关的函数返回地址。
2 多线程编程的基础是栈,栈是多线程编程的基础,每一个线程都最少有一个自己专属的栈,用来存储本线程运行时各个函数的临时变量和函数调用和函数返回值。操作系统最基本的功能是支持多线程编程,支持中断和异常处理,每一个线程都有专属的栈,中断和异常也有专属的栈,栈是操作系统多线程管理的基础。
4 c++的内存管理介绍⭐⭐⭐⭐⭐
在c++中,虚拟内存分为代码段、数据段、BSS段、堆区、文件映射区及栈区。
代码段:包括制度存储区、文本区,其中只读存储区存储字符串常量,文本区存储程序的机器代码。
数据段:存储程序中已初始化的全局变量和静态变量。
BSS段:存储未出啥的全局变量和静态变量(局部+全局),以及所有被初始化为的全局变量和静态变量。
堆区:调用new/malloc函数时在堆区动态分配内存,同时需要调用delete/free来手动释放申请的内存。
映射区:存储动态链接库以及调用mmap函数进行的文件映射。
栈区:使用栈空间存储函数的返回地址、参数、局部变量、返回值。
5 内存泄漏⭐⭐⭐⭐⭐
内存泄漏是什么?
内存泄漏是指在计算机程序运行时,内存动态分配后,由于疏忽或者错误导致内存无法被正确释放,最终导致内存被占用过多,从而程序出现错误甚至崩溃的问题。内存泄漏是一种非常严重的程序问题,需要引起足够的重视。
通常,内存泄漏是由于程序员在动态分配内存时,没有正确的释放内存导致的。如果没有进行内存释放操作,就会导致一个不断增长的内存空间,最终用完系统内存资源从而导致程序崩溃。一些常见的内存泄漏情况包括:
1 动态分配内存后,忘记释放掉。
2 对已经释放的内存空间进行
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
该专栏面向嵌入式开发工程师、C++开发工程师,包括C语言、C++,操作系统,ARM架构、RTOS、Linux基础、Linux驱动、Linux系统移植、计算机网络、数据结构与算法、数电基础、模电基础、5篇面试题目、HR面试常见问题汇总和嵌入式面试简历模板等文章。超全的嵌入式软件工程师面试题目和高频知识点总结! 另外,专栏分为两个部分,大家可以各取所好,为了有更好的阅读体验,后面会持续更新!!!