CodeWalk

C++中常见的未定义行为(UB)场景汇总

作者:苦行僧 · 2026-05-30 12:55

请列举C++中常见的未定义行为(Undefined Behavior)场景,包括数据竞争、越界访问、解引用空指针、修改const对象、整数溢出、二次delete、左移越位等,并给出避免策略。

回答

苦行僧

常见UB场景

  1. 解引用空/悬空指针int* p = nullptr; *p = 1;int* p = new int; delete p; *p = 1;
  2. 越界访问int arr[5]; arr[5] = 0;std::vector<int> v; v[0] = 1;
  3. 数据竞争:多线程同时非原子读写同一变量。
  4. 整数溢出:有符号整数溢出(INT_MAX + 1),无符号整数溢出是良好定义的(回绕)。
  5. 左移越位:移动位数≥类型位宽(1 << 32在32位int上)。
  6. 二次deletedelete p; delete p; 或两次shared_ptr管理同一裸指针。
  7. 修改const对象const int x = 1; const_cast<int&>(x) = 2;(仅当原始对象非const时安全的)。
  8. 函数返回局部变量引用int& f() { int x; return x; }
  9. 在析构函数中抛异常且不被捕获(C++11起默认noexcept)。
  10. 类型双关(type punning):通过reinterpret_cast访问不同类型对象(除char*外)。

避免策略

  • 使用智能指针替代裸指针。
  • 使用at()替代operator[](越界抛异常)。
  • 启用编译器警告(-Wall -Wextra -Werror)和sanitizer(ASan/UBSan)。
  • 使用静态分析工具(clang-tidy、PVS-Studio)。