C++未定义行为(undefined behavior)
发布时间 - 2026-01-10 22:59:50 点击率:次衡量一个人是否真正活着的根本方法,就是看他是否有意愿、有能力做出主动的选择。

在计算机程序设计中,未定义行为(undefined behavior)是指行为不可预测的计算机代码。这是一些编程语言的一个特点,最有名的是在C语言中。在这些语言中,为了简化标准,并给予实现一定的灵活性,标准特别地规定某些操作的结果是未定义的,这意味着程序员不能预测会发生什么事。
一个问题
此问题摘自知乎:
对顺序容器 ( vector ) 的访问:
如果使用 operator[] 访问容器,下标越界是未定义行为。
使用 at 访问,下标越界,则抛出一个 out_of_range 异常。
下标越界应该是明显错误的,但是为什么 C++ 标准选择把 operator[] 列为未定义行为,而加入at成员在对成员访问时进行下标检查?
同样摘取一些回答
回答一:
C++ 的设计理念之一,就是你不需要为你不使用的特性付出代价。如果你能确保你的下标不越界,C++就不会进行检查。
回答二:
检查就表示有运算判断的开销,C++将效率放在第一位,假设用户之前已经对[]访问的下标做过检查了,在一个大量访问的for循环中,但是vector还是自作聪明的每次都判断一次下标越界,这个效率影响你可想而知!你会不会在这个情况下骂它管的太多呢。所以说将所有的权利都交给你,vector不做太多自作聪明的处理。
什么是未定义
未定义行为(Undefined Behavior)是指语言标准未做规定的行为。同时,标准也从没要求编译器判断未定义行为,所以这些行为有编译器自行处理,在不同的编译器可能会产生不同的结果,又或者如果程序调用未定义的行为,可能会成功编译,甚至一开始运行时没有错误,只会在另一个系统上,甚至是在另一个日期运行失败。当一个未定义行为的实例发生时,正如语言标准所说,“什么事情都可能发生”,也许什么都没有发生。
下文会罗列C++中的一系列未定义结果和未定义行为,持续整理更新。
未定义的结果
1、当我们赋给带符号类型一个超出它表示范围的值时,结果是未定义的。
signed char c2 = 256; // c2的值是未定义的
2、函数体之内定义的变量:未初始化(uninitialized),其值undefined。
3、算术表达式有可能产生未定义的结果
数学性质本身:除数为0
计算机的特点:溢出;很多系统在编译和运行时都不报出溢出错误,像其他未定义的行为一样,溢出的结果是不可预知的。
未定义的行为
未定义行为,无法预估Runtime会发生什么(unpredictable:normal、crashing、incorrect results)。
1、解引用空指针、非法迭代器或者尾后迭代器都是未定义行为
2、访问一个无效数组索引,下标越界
3、当derived class对象经由一个base class指针被删除,而该base class带着一个non-virtual析构函数,其结果是未定义的。
实际执行时通常发生的是对象的derived成员没有被销毁。
4、在两个异常同时存在的情况下,程序若不是结束执行就是导致未定义行为。
5、释放一个非new分配的内存,或者将相同的指针值释放多次,其行为是未定义的。
6、string s(s2,pos2); // s是string s2从下标pos2开始的字符拷贝,如果pos2>s2.size(),构造函数的行为未定义
7、试图比较两个无关地址是未定义行为
8、对于那些没有指定执行顺序的运算符来说,如果表达式指向并修改了同一个对象,将会引发错误并产生未定义的行为。
int i=0; cout<<i<<" "<<++i<<endl; // 未定义 // 编译器可能先求++i的值,再求i的值;也可能先求i的值,再求++i的值。注意与print函数的区别。 *beg=toupper(*beg++); // 未定义
9、对有符号数进行左移操作可能会改变符号位的值,因此是一种未定义的行为。移位运算符右侧的运算对象一定不能为负,而且值必须严格小于结果的位数,否则就会产生未定义的行为。
10、使用static_cast将void*转换成其他类型指针,必须确保转换后所得的类型就是指针所指的类型。类型一旦不符,将产生未定义行为。
double d; void* p=&d; double *dp=static_cast<double*>(p);
11、const_cast只能改变运算对象的底层const,如果对象本身是一个常量,使用const_cast执行写操作就会产生未定义行为。
12、不要使用get初始化另一个智能指针或为智能指针赋值,否则将会产生两个独立的shared_ptr指向相同的内存,这将产生未定义行为。
13、delete []p;如果忘记[],其行为是未定义的。 删除单一对象的指针加[],其行为也是未定义的。
# c
# 未定义行为
# c语言未定义行为
# undefined
# behavior
# 就会
# 是在
# 太多
# 结果是
# 将会
# 是指
# 自作聪明
# 的是
# 都是
# 运算符
# 是一个
# 这是
# 情况下
# 迭代
# 是一种
# 带着
# 都不
# 在这个
# 有可能
# 你会
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
php中::能调用final静态方法吗_final修饰静态方法调用规则【解答】
Java解压缩zip - 解压缩多个文件或文件夹实例
网站页面设计需要考虑到这些问题
如何打造高效商业网站?建站目的决定转化率
javascript中的数组方法有哪些_如何利用数组方法简化数据处理
Laravel怎么实现模型属性的自动加密
高防服务器租用指南:配置选择与快速部署攻略
Edge浏览器怎么启用睡眠标签页_节省电脑内存占用优化技巧
Laravel Eloquent性能优化技巧_Laravel N+1查询问题解决
Laravel Eloquent访问器与修改器是什么_Laravel Accessors & Mutators数据处理技巧
长沙企业网站制作哪家好,长沙水业集团官方网站?
Laravel API资源(Resource)怎么用_格式化Laravel API响应的最佳实践
Laravel如何实现邮箱地址验证功能_Laravel邮件验证流程与配置
JS中页面与页面之间超链接跳转中文乱码问题的解决办法
百度输入法ai组件怎么删除 百度输入法ai组件移除工具
Bootstrap整体框架之CSS12栅格系统
Laravel怎么防止CSRF攻击_Laravel CSRF保护中间件原理与实践
Win11怎么开启自动HDR画质_Windows11显示设置HDR选项
Laravel如何实现全文搜索_Laravel Scout集成Algolia或Meilisearch教程
如何自己制作一个网站链接,如何制作一个企业网站,建设网站的基本步骤有哪些?
zabbix利用python脚本发送报警邮件的方法
JS中对数组元素进行增删改移的方法总结
网站制作价目表怎么做,珍爱网婚介费用多少?
PHP怎么接收前端传的文件路径_处理文件路径参数接收方法【汇总】
Laravel如何使用模型观察者?(Observer代码示例)
湖南网站制作公司,湖南上善若水科技有限公司做什么的?
Laravel如何使用Eloquent进行子查询
使用豆包 AI 辅助进行简单网页 HTML 结构设计
如何用景安虚拟主机手机版绑定域名建站?
哪家制作企业网站好,开办像阿里巴巴那样的网络公司和网站要怎么做?
php 三元运算符实例详细介绍
悟空识字如何进行跟读录音_悟空识字开启麦克风权限与录音
Java遍历集合的三种方式
如何用搬瓦工VPS快速搭建个人网站?
Laravel中的Facade(门面)到底是什么原理
香港服务器建站指南:免备案优势与SEO优化技巧全解析
Laravel怎么导出Excel文件_Laravel Excel插件使用教程
轻松掌握MySQL函数中的last_insert_id()
北京专业网站制作设计师招聘,北京白云观官方网站?
浅述节点的创建及常见功能的实现
Python高阶函数应用_函数作为参数说明【指导】
厦门模型网站设计制作公司,厦门航空飞机模型掉色怎么办?
JavaScript如何实现路由_前端路由原理是什么
简历没回改:利用AI润色让你的文字更专业
浅谈javascript alert和confirm的美化
如何在阿里云购买域名并搭建网站?
HTML 中动态设置元素 name 属性的正确语法详解
制作公司内部网站有哪些,内网如何建网站?
Python文件操作最佳实践_稳定性说明【指导】
Laravel如何为API编写文档_Laravel API文档生成与维护方法

