0

0

c++中的未定义行为(UB)有哪些_c++常见Undefined Behavior汇总【安全编程】

穿越時空

穿越時空

发布时间:2025-12-22 15:35:09

|

648人浏览过

|

来源于php中文网

原创

未定义行为(UB)是C++标准完全不约束后果的行为,编译器可任意优化或生成错误代码;常见于数组/指针越界、解引用空/野/已释放指针等场景,极易引发安全漏洞。

c++中的未定义行为(ub)有哪些_c++常见undefined behavior汇总【安全编程】

未定义行为(Undefined Behavior,UB)不是“随机出错”,而是标准完全不管后果——编译器可以优化、忽略、崩溃、静默改值,甚至生成看似正常但实际错得离谱的代码。 它是C++中最危险也最容易被忽视的安全隐患,尤其在底层开发、嵌入式、安全敏感场景中,一个UB可能直接导致内存破坏、提权漏洞或逻辑失控。

访问越界:数组、指针、容器

超出合法索引范围读写,是UB最高发的来源之一:

  • int a[3] = {1,2,3}; a[5] = 42; —— 数组下标越界(即使没崩溃,也不保证安全)
  • int* p = new int[2]; p[3] = 0; —— new分配后越界写,UB,不触发std::bad_alloc
  • std::vector v{1,2}; v.at(5); —— at()会抛异常,但v[5]是UB(operator[]不检查)
  • char buf[10]; strcpy(buf, "hello world"); —— 缓冲区溢出,经典UB,也是溢出漏洞根源

解引用空/野/已释放指针

指针失效后继续使用,结果不可预测:

  • int* p = nullptr; *p = 1; —— 解引用空指针,UB(不是“一定段错误”,优化后可能被整个删掉)
  • int* p = new int(42); delete p; cout —— 使用已释放内存(dangling pointer),UB
  • int* p; cout —— 未初始化指针解引用,UB(哪怕只是读,也可能触发陷阱值)
  • int x = 10; int* p = &x; } /* x析构 */ cout —— 访问已离开作用域的局部对象,UB

有符号整数溢出与未定义运算

无符号整数溢出是定义良好的(自动回绕),但有符号整数溢出是UB:

聚蜂消防BeesFPD
聚蜂消防BeesFPD

关注消防领域的智慧云平台

下载

立即学习C++免费学习笔记(深入)”;

  • int x = INT_MAX; x++; —— 有符号加法溢出,UB(编译器可假设它永不发生,进而删除相关分支)
  • int y = -1; y —— 左移导致符号位变化或溢出,UB(右移负数也是UB)
  • int a = 1, b = 0; a / b; —— 除零,UB(浮点除零是特殊值,整数除零是纯UB)
  • int x; cout —— 读取未初始化的非静态局部变量,UB(静态变量会零初始化,但自动存储期变量不会)

违反严格别名规则与类型双关

C++禁止用不兼容类型指针访问同一块内存(防止编译器优化失准):

  • float f = 3.14f; int* p = (int*)&f; cout —— C风格强制转换绕过类型系统,UB
  • union { int i; float f; } u; u.f = 3.14f; cout —— 在C++中(C++17前)读取非最后写入成员是UB;C++17起允许“活跃成员切换”,但仍有严格限制
  • char buf[sizeof(int)]; int* p = reinterpret_cast(buf); *p = 42; —— 未满足对齐要求或未正确构造对象,UB(需用placement new或std::bit_cast(C++20))

基本上就这些。UB不复杂,但容易忽略;它不总当场报错,却可能在优化后、换平台后、或攻击者精心构造输入时才爆发。用AddressSanitizer(ASan)、UndefinedBehaviorSanitizer(UBSan)、Clang-Tidy和静态分析工具主动捕获,比靠运气更可靠。

相关专题

更多
string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

315

2023.08.02

int占多少字节
int占多少字节

int占4个字节,意味着一个int变量可以存储范围在-2,147,483,648到2,147,483,647之间的整数值,在某些情况下也可能是2个字节或8个字节,int是一种常用的数据类型,用于表示整数,需要根据具体情况选择合适的数据类型,以确保程序的正确性和性能。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

537

2024.08.29

c++怎么把double转成int
c++怎么把double转成int

本专题整合了 c++ double相关教程,阅读专题下面的文章了解更多详细内容。

52

2025.08.29

C++中int的含义
C++中int的含义

本专题整合了C++中int相关内容,阅读专题下面的文章了解更多详细内容。

197

2025.08.29

堆和栈的区别
堆和栈的区别

堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

388

2023.07.18

堆和栈区别
堆和栈区别

堆(Heap)和栈(Stack)是计算机中两种常见的内存分配机制。它们在内存管理的方式、分配方式以及使用场景上有很大的区别。本文将详细介绍堆和栈的特点、区别以及各自的使用场景。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

571

2023.08.10

空指针异常处理
空指针异常处理

本专题整合了空指针异常解决方法,阅读专题下面的文章了解更多详细内容。

22

2025.11.16

数据库Delete用法
数据库Delete用法

数据库Delete用法:1、删除单条记录;2、删除多条记录;3、删除所有记录;4、删除特定条件的记录。更多关于数据库Delete的内容,大家可以访问下面的文章。

269

2023.11.13

Golang gRPC 服务开发与Protobuf实战
Golang gRPC 服务开发与Protobuf实战

本专题系统讲解 Golang 在 gRPC 服务开发中的完整实践,涵盖 Protobuf 定义与代码生成、gRPC 服务端与客户端实现、流式 RPC(Unary/Server/Client/Bidirectional)、错误处理、拦截器、中间件以及与 HTTP/REST 的对接方案。通过实际案例,帮助学习者掌握 使用 Go 构建高性能、强类型、可扩展的 RPC 服务体系,适用于微服务与内部系统通信场景。

0

2026.01.15

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
国外Web开发全栈课程全集
国外Web开发全栈课程全集

共12课时 | 1.0万人学习

进程与SOCKET
进程与SOCKET

共6课时 | 0.3万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号