编程系统开发者,后端开发者

什么是C++中的未定义行为(undefined behavior),它为什么如此危险?请举例并解释如何避免它。

用 Hintsage AI 助手通过面试

答案。

未定义行为(UB,未定义行为)是指代码中的某些操作,其行为没有在标准中定义。在这种情况下,编译器可以做出任何决定:程序可能在不同的平台、编译器上表现不同,甚至可能引发核战争(这是一个比喻!)。使用UB是C++中最危险的错误。

UB的例子:

  • 数组越界访问
  • 使用未初始化的变量
  • 双次释放同一内存区域
  • 使用悬空指针(dangling pointers)
int* p = new int[2]; delete[] p; int x = p[1]; // UB: 释放后访问内存

为了防止UB:

  • 始终初始化变量;
  • 检查数组/容器的边界;
  • 避免手动内存管理,使用智能指针。

陷阱问题。

以下代码会发生什么?

int a = 42; int b = a++ + ++a;

b将会拥有什么值?

答案:

这段代码会导致UB,因为在操作之间没有序列点(sequence points)来修改和读取变量a。标准未保证确定的结果,编译器可能得到任何结果或甚至生成意外的代码。

由于不了解这一主题的细微之处而导致的实际错误示例。


故事 在一个数据存储系统的项目中,一位开发者在低级函数中出现了数组越界错误。UB仅在特定的用户数据上表现出来,导致文件结构损坏和客户数据丢失。


故事 在微控制器项目中,出现了读取未初始化变量的结构。测试通过了,但在设备发布一年后发现了随机错误,这是由于UB引起的:变量有时包含垃圾值。


故事 在一个大型开源项目中,发现一个描述符在不同代码部分被释放两次。这种UB起初表现得非常少见,但在新版本的操作系统中导致了频繁的崩溃。