CSIG 腾讯后台
new和malloc区别
- "new"是C++的一个操作符,它在创建对象时会自动调用构造函数。"malloc"是C语言的函数,仅仅分配内存。
- "new"返回的是对象类型的指针,类型与对象的类型保持一致,无需类型转换,而"malloc"函数返回的是void类型的指针,需要转换为实际的对象类型的指针。
- "new"在无法分配内存时会抛出异常。"malloc"在无法分配内存时返回NULL。
操作系统分配内存的单位
操作系统分配内存的单位是页面(Page)。
操作系统分配一页,这一页一定可读可写可执行吗
不会,操作系统分配的一页内存是否可读、可写、可执行由页表中的访问权限位(RWX)决定,不是所有的页默认都具有这些权限。
访问malloc分配的指针一定偏移之后的地址会怎样
偏移后如果超过了malloc
分配的内存区域,访问这个地址会是未定义行为(Undefined Behavior - UB)。
什么情况下会触发Segmentation Fault
Segmentation Fault通常会在以下情况触发:
- 解引用空指针。
- 访问野指针指向的内存。
- 数组或内存越界访问。
- 对同一个内存地址进行多次
delete
或free
。
free两次如何定位第一次free的位置
可以使用工具如Valgrind
进行内存检测,或使用g++
的-fsanitize=address
编译选项,这将在程序运行时检测到两次free
并报告第一次free
的位置。
析构器的调用顺序(先派生类后基类)
析构器的调用顺序是先调用派生类的析构函数,然后调用基类的析构函数。
内层函数抛异常,外层函数catch到,中间层函数的局部变量是否会调用析构器
会被调用。这是因为C++支持异常的栈展开(stack unwinding)机制,确保在抛出异常后,并在异常传播过程中,释放栈上对象的资源。
如果析构时又抛异常,catch的是哪一个,如果是新的,老异常还能捕捉到么
当析构函数在异常处理过程中又抛出异常,而在当前作用域中未对其进行捕获处理,程序将调用 std::terminate()
,通常导致程序非正常退出。C++标准规定,在一个异常已经被抛出的情况下,如果在析构过程中再次抛出一个异常而未被当前析构函数内部捕获,则处理器无法同时处理两个并发的异常,因而只能调用 std::terminate()
。
因此,如果析构时抛出了一个新的异常,之前的异常将不再被捕捉到,因为程序在这种情况下会被终止。为了避免这种情况,你应将析构函数设计为不抛出异常,或者在其中捕获并处理任何可能抛出的异常。这通常是通过将析构函数标记为 noexcept
或在析构函数中使用 try-catch 语句来确保不退出到析构函数外部来实现的。
异常的底层原理了解么,汇编层面上的
异常处理的底层原理可以简要概括如下:
- 栈展开(Stack Unwinding):当异常被抛出时,程序需要找到合适的异常处理代码来处理这个异常。这个过程涉及到逆向遍历调用栈,逐层检查是否有匹配的异常处理代码(catch块)。这个遍历过程被称为栈展开。在栈展开过程中,局部对象会被析构,以保证资源得到释放。
- 异常表(Exception Table):编译器在编译过程中会生成异常表,这个表包含了函数中可能抛出异常的位置信息,以及对应的异常处理代码的位置信息。当异常发生时,异常处理机制会利用这个表来定位需要跳转到的catch块的位置。
- 跳转(Jump):一旦找到匹配的异常处理代码,程序会执行一个无条件跳转到该处理代码的开始位置。这个跳转是通过修改程序计数器(Program Counter, PC)实现的,跳过了中间的所有代码,直接到达异常处理代码的位置。
- 捕获异常(Catching Exceptions):异常处理代码(catch块)开始执行。在这个阶段,异常对象通常会被拷贝或引用到一个局部变量中,以便于在catch块中进行处理。
- 恢复正常执行流程:一旦catch块处理完毕,程序会继续执行紧接着try-catch结构之后的代码,恢复到正常的执行流程。
从汇编的角度看,异常处理涉及到调整栈指针(SP)、程序计数器(PC)以及可能的寄存器操作,以确保资源的正确释放和代码的正确跳转。
c++哪个特性类似go interface
在C++中,与Go语言的interface类似的特性是抽象基类和纯虚函数。
简而言之,C++的抽象基类通过声明至少一个纯虚函数来定义接口规范,从而模仿了Go的interface行为。纯虚函数在C++中使用=0
语法声明,表示该函数没有实现,从而要求所有派生类必须提供该函数的具体实现。
纯虚函数能有方法体么
是的,纯虚函数在C++中可以有方法体。尽管纯虚函数被定义为没有实现的函数(通过=0
语法指定),这意味着派生类必须提供该函数的实现以实现多态,但是C++允许为纯虚函数提供定义。
这样做的目的是允许基类提供一个默认的实现,派生类可以选择是否使用或覆盖它。但是,即便为纯虚函数提供了实现,拥有纯虚函数的类仍然是抽象类,不能被实例化。
收集整理了一份2024年最新C++开发学习资料,既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C++开发知识点,真正体系化!
包含大厂面经、学习笔记、实战项目、大纲路线、讲解视频 领取 君羊739729163 或者
https://docs.qq.com/doc/DR2N4d25LRG1leU9Q
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。