持续更新版本 嵌入式工程师常见面试题( 四 )


1、new 和的区别?
new 和都是用于动态分配内存的方法,但是它们在以下方面存在一些区别:
内存分配位置:new 操作从自由存储区为对象动态分配内存空间,而函数从堆上动态分配内存 。自由存储区不仅可以是堆,还可以是静态存储区,这取决于 new 在哪里为对象分配内存 。返回类型安全性:new 操作符内存分配成功时,返回的是对象类型的指针,与对象类型严格匹配,无需进行类型转换,因此 new 是符合类型安全性的操作符 。而函数在内存分配成功后返回的是 void*,需要通过强制类型转换将 void* 指针转换成所需类型 。内存分配失败时的返回值:当 new 内存分配失败时,会抛出异常,不会返回 NULL;而内存分配失败时,返回 NULL 。是否需要指定内存大小:使用new申请内存时,不需要指定内存块的大小,编译器会根据类型信息自行计算;而则需要显式地指出所需内存块的大小 。
总的来说,new和在内存分配位置、返回类型安全性、内存分配失败时的返回值以及是否需要指定内存大小等方面存在差异 。
2、的底层实现
(1)当开辟的空间小于 128K 时,调用 brk()函数,的底层实现是系统调用函数 brk(),其主要移动指针 (此时的指的是 Linux 地址空间中堆段的末尾地址,不是数据段的末尾地址)
(2)当开辟的空间大于 128K 时,mmap()系统调用函数来在虚拟地址空间中(堆和栈中间,称为“文件映射区域”的地方)找一块空间来开辟 。
3、在1G内存的计算机中能否(1.2G)?为什么?
在1G内存的计算机中,无法使用(1.2G) 。
在C语言中,()函数用于动态分配内存 。当使用()请求超过可用内存的大小时,会发生两种情况:
分配失败:如果请求的内存大小超过了操作系统可用的内存大小,()将返回NULL,表示分配失败 。在这种情况下,程序将无法继续执行 。分配成功但导致崩溃:如果请求的内存大小超过了可用的内存大小,但()仍然返回了非NULL的指针,这通常是由于操作系统使用了内存映射技术或虚拟内存机制 。这种情况下,程序可能会继续执行,但它可能会遇到未定义的行为,例如访问已分配的内存时崩溃或导致性能下降 。
在1G内存的计算机中,由于可用内存只有1GB,因此无法使用(1.2G),因为这将请求超过可用内存大小的内存大小 。如果尝试这样做,()将返回NULL,并且程序将无法继续执行 。
4、指针与引用的相同和区别;如何相互转换?
引用时C++独有的特性,而指针则是C/C++都有的,它们有一些相似之处,但也有很多区别 。
相同点:不同点:相互转换:
总的来说,指针和引用在功能和使用上有一些区别,需要根据具体情况选择使用哪种方式 。
5、"C”的作用
"C"是一个C语言链接器的关键字,它有以下几个作用:
使得在C++中使用C编译方式成为可能,指明该函数使用C编译方式 。
在某些情况下,使用 "C"声明函数,可以使得C++编译器按照C语言的方式对函数进行编译和链接,从而能够正确地调用该函数 。
"C"可以用于在C++中调用由C语言编写的库函数 。因为C++与C语言的函数调用方式不同,使用 "C"可以指明该函数使用C语言的方式进行链接,避免因为链接方式不同而导致的错误 。
在使用动态链接库(DLL)时,使用 "C"可以保证函数的导出和导入与C语言一致 。
总之,"C"的作用是为了在C++中使用C语言的编译和链接方式,并且在一些特定情况下保证函数的正确导出和导入 。
6、重写()函数需要注意哪些问题,()那些函数会导致内存溢出?
重写()函数时需要注意以下问题: