2024最新大厂C++面试真题合集,大厂面试百日冲刺 day11

CSIG 腾讯后台

new和malloc区别

  1. "new"是C++的一个操作符,它在创建对象时会自动调用构造函数。"malloc"是C语言的函数,仅仅分配内存。
  2. "new"返回的是对象类型的指针,类型与对象的类型保持一致,无需类型转换,而"malloc"函数返回的是void类型的指针,需要转换为实际的对象类型的指针。
  3. "new"在无法分配内存时会抛出异常。"malloc"在无法分配内存时返回NULL。

操作系统分配内存的单位

操作系统分配内存的单位是页面(Page)。

操作系统分配一页,这一页一定可读可写可执行吗

不会,操作系统分配的一页内存是否可读、可写、可执行由页表中的访问权限位(RWX)决定,不是所有的页默认都具有这些权限。

访问malloc分配的指针一定偏移之后的地址会怎样

偏移后如果超过了malloc分配的内存区域,访问这个地址会是未定义行为(Undefined Behavior - UB)。

什么情况下会触发Segmentation Fault

Segmentation Fault通常会在以下情况触发:

  1. 解引用空指针。
  2. 访问野指针指向的内存。
  3. 数组或内存越界访问。
  4. 对同一个内存地址进行多次deletefree

free两次如何定位第一次free的位置

可以使用工具如Valgrind进行内存检测,或使用g++-fsanitize=address编译选项,这将在程序运行时检测到两次free并报告第一次free的位置。

析构器的调用顺序(先派生类后基类)

析构器的调用顺序是先调用派生类的析构函数,然后调用基类的析构函数。

内层函数抛异常,外层函数catch到,中间层函数的局部变量是否会调用析构器

会被调用。这是因为C++支持异常的栈展开(stack unwinding)机制,确保在抛出异常后,并在异常传播过程中,释放栈上对象的资源。

如果析构时又抛异常,catch的是哪一个,如果是新的,老异常还能捕捉到么

当析构函数在异常处理过程中又抛出异常,而在当前作用域中未对其进行捕获处理,程序将调用 std::terminate(),通常导致程序非正常退出。C++标准规定,在一个异常已经被抛出的情况下,如果在析构过程中再次抛出一个异常而未被当前析构函数内部捕获,则处理器无法同时处理两个并发的异常,因而只能调用 std::terminate()

因此,如果析构时抛出了一个新的异常,之前的异常将不再被捕捉到,因为程序在这种情况下会被终止。为了避免这种情况,你应将析构函数设计为不抛出异常,或者在其中捕获并处理任何可能抛出的异常。这通常是通过将析构函数标记为 noexcept 或在析构函数中使用 try-catch 语句来确保不退出到析构函数外部来实现的。

异常的底层原理了解么,汇编层面上的

异常处理的底层原理可以简要概括如下:

  1. 栈展开(Stack Unwinding):当异常被抛出时,程序需要找到合适的异常处理代码来处理这个异常。这个过程涉及到逆向遍历调用栈,逐层检查是否有匹配的异常处理代码(catch块)。这个遍历过程被称为栈展开。在栈展开过程中,局部对象会被析构,以保证资源得到释放。
  2. 异常表(Exception Table):编译器在编译过程中会生成异常表,这个表包含了函数中可能抛出异常的位置信息,以及对应的异常处理代码的位置信息。当异常发生时,异常处理机制会利用这个表来定位需要跳转到的catch块的位置。
  3. 跳转(Jump):一旦找到匹配的异常处理代码,程序会执行一个无条件跳转到该处理代码的开始位置。这个跳转是通过修改程序计数器(Program Counter, PC)实现的,跳过了中间的所有代码,直接到达异常处理代码的位置。
  4. 捕获异常(Catching Exceptions):异常处理代码(catch块)开始执行。在这个阶段,异常对象通常会被拷贝或引用到一个局部变量中,以便于在catch块中进行处理。
  5. 恢复正常执行流程:一旦catch块处理完毕,程序会继续执行紧接着try-catch结构之后的代码,恢复到正常的执行流程。

从汇编的角度看,异常处理涉及到调整栈指针(SP)、程序计数器(PC)以及可能的寄存器操作,以确保资源的正确释放和代码的正确跳转。

c++哪个特性类似go interface

在C++中,与Go语言的interface类似的特性是抽象基类纯虚函数

简而言之,C++的抽象基类通过声明至少一个纯虚函数来定义接口规范,从而模仿了Go的interface行为。纯虚函数在C++中使用=0语法声明,表示该函数没有实现,从而要求所有派生类必须提供该函数的具体实现。

纯虚函数能有方法体么

是的,纯虚函数在C++中可以有方法体。尽管纯虚函数被定义为没有实现的函数(通过=0语法指定),这意味着派生类必须提供该函数的实现以实现多态,但是C++允许为纯虚函数提供定义。

这样做的目的是允许基类提供一个默认的实现,派生类可以选择是否使用或覆盖它。但是,即便为纯虚函数提供了实现,拥有纯虚函数的类仍然是抽象类,不能被实例化。

收集整理了一份C++开发学习资料,既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升
包含大厂面经、学习笔记、实战项目、大纲路线、讲解视频 领取 君羊739729163 网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

  • 7
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值