- 博客(33)
- 收藏
- 关注
原创 C/C++ 核心准则:不可重复释放资源
由于多种原因,资源管理系统可能难以甚至无法预先判断资源是否已被回收,一旦重复释放资源,会直接破坏资源管理系统的数据结构,导致不可预期的错误。在 C++ 代码中,应使资源接受类对象的管理,避免分散地分配回收资源,可参见。重复释放资源会导致标准未定义的行为。
2024-10-16 10:36:54
330
原创 C/C++ 核心准则:避免空指针解引用
在 C++ 理论体系中,如果 P 为指针类型的表达式, *P 总应指代有效的对象或函数,形如 P->M、P->*M 的表达式等同于 (*P).M、(*P).*M,形如 P[N] 的表达式等同于 *(P + N),如果 P 或 P + N 没有指向有效的对象或函数,程序的行为是未定义的。空指针与任何已指向对象或函数的指针均不相等,通过空指针访问对象是非法的,其后果在语言标准中是未定义的,执行环境一般会拒绝程序访问空指针对应的地址,使程序无法正常运行。空指针解引用会导致标准未定义的行为。
2024-10-14 14:38:55
413
原创 C++ 核心资源管理准则:使资源接受类对象的管理
将 FindFirstFile 及其相关数据封装成一个类,由 unique_ptr 对象保存 FindFirstFile 的结果,FindClose 是资源的回收方法,将其作为 unique_ptr 对象的组成部分,使资源可以被自动回收。则称 Owner 类的对象 obj 拥有资源的所有权,当 obj 的生命周期结束后,相关资源会被自动回收,从而避免了在复杂的流程分枝中手工回收资源,有效提高了资源管理的安全性。本规则是 C++ 核心资源管理准则 — “
2024-10-14 14:01:40
402
原创 避免内存泄露
当 realloc 函数分配失败时会返回空指针,p 指向的原内存空间不会被释放,但 p 被赋值为空,导致内存泄漏,这是一种常见错误。例中局部变量 p 记录已分配的内存地址,释放前在某种情况下函数返回,之后便再也无法访问到这块内存了,导致内存泄漏。程序需要保证内存分配与回收之间的流程可达,且不可被异常中断,相关线程也不可在中途停止。动态分配的内存地址不可被遗失,否则相关内存无法被访问也无法被回收,这种问题称为“本规则是 ID_resourceLeak 的特化。”,会导致可用内存被耗尽,使程序无法正常运行。
2024-10-14 13:20:24
183
原创 C/C++ 核心准则:形参与实参均为数组时,数组大小应一致
被声明为数组的形式参数等同于指针,对传入的实际参数起不到限制作用,为了避免潜在的问题,当实际参数也是数组时,应要求实际参数与形式参数具有相同的元素个数。在 C++ 代码中建议使用 std::array 等容器代替 C 数组,可参见 ID_forbidCArray 的进一步讨论。例中 foo 函数的形式参数被声明为具有 10 个元素的数组,而实际传入的数组只有 5 个参数,但这种代码可以通过编译。
2024-10-14 11:42:26
140
原创 C/C++ 核心准则:不应将数组作为函数的形式参数
例中 foo 函数声明的数组参数有 5 个元素,传入的实际参数只有 3 个元素,往往意味着错误,但可以通过编译。用空的方括号声明数组,并用另一个参数表示数组大小的情况可不受本规则限制,但在 C++ 代码中不建议使用这种方式。被声明为数组的形式参数等同于指针,第一个维度的大小声明对传入的实际参数起不到限制作用。这样数组大小不一致便无法通过编译。
2024-10-14 11:28:00
94
原创 C/C++ 核心准则:sizeof 不应作用于数组参数
例中参数 a 是一个指针,sizeof(a) 等同于 sizeof(char*),而不是 sizeof(char[10])。被声明为数组的形式参数等同于指针,对其使用 sizeof 无法获取到数组大小,往往意味着错误。这样 sizeof(a) 便等同于 sizeof(char[10])。
2024-10-14 11:02:01
100
原创 避免资源泄漏
另外,动态分配的资源均应在合理的时机回收,避免占用的资源只增不减,最终导致资源耗尽。对于长期运行的服务类程序,如果攻击者能够掌握导致资源分配而不会释放的外部操作,便形成了可被利用的安全漏洞,攻击者可以耗尽资源使系统瘫痪,这也是“拒绝服务攻击”的一种形式。对于动态分配的资源,其地址、句柄或描述符等标志性信息不可被遗失,否则资源无法被访问也无法被回收,这种问题称为“资源泄漏”,会导致资源耗尽或死锁等问题,使程序无法正常运行。例中变量 fd 记录文件资源描述符,在回收资源之前对其重新赋值会导致资源泄漏。
2024-10-14 10:31:18
222
原创 C/C++ 核心准则:避免分配大小为零的内存空间
当申请分配的内存空间大小为 0 时,malloc、calloc、realloc 等函数的行为是由实现定义的,可以分配元素个数为 0 的数组,也可以不进行任何分配,直接返回空指针。在这种情况下,C++ 语言的 new 运算符会分配元素个数为 0 的数组,但这种数组往往没有实际价值,而且要注意元素个数为 0 的数组也需要被释放。如果 malloc 的返回值不为空,并不能保证其分配的内存空间是可用的,如果不加判断就就直接访问会导致缓冲区溢出等问题。
2024-10-12 12:03:35
84
原创 C/C++ 核心准则:避免缓冲区溢出
连续的内存区域均可称为缓冲区,如数组等。在进程实际的内存布局中,pswd 数组之后可以是 auth 函数的返回地址,如果攻击者利用缓冲区溢出将其篡改,便可以扰乱程序的执行,甚至可以绕过用于判断的 if 语句,直接执行用于显示敏感信息的 show_secret 函数,造成敏感信息泄露。例中 auth 函数验证用户输入的密码,密码存于数组 pswd 中,gets 函数接收用户输入,但不检查输入长度,一旦输入超过 8 个字符就会造成缓冲区溢出,由于 gets 函数过于危险,已从 C11 标准中移出。
2024-10-11 11:47:47
267
原创 C++ 析构函数注意事项
析构函数是一个特殊的成员函数,它在对象生命周期结束时自动调用,用于执行清理工作,如释放分配给对象的内存、关闭文件、断开网络连接等。正确编写析构函数对于防止内存泄漏、资源泄露和其他资源管理问题至关重要。
2024-09-27 18:25:15
917
原创 C++ 异常安全(五):保障异常安全
设 lock 是某种获取资源的操作,unlock 是释放资源的操作,procedure_may_throw 是可能抛出异常的过程,那么 bar 函数就不是异常安全的,一旦抛出异常就会导致死锁或泄漏等问题。先处理对象的副本,处理成功后交换副本与对象的数据,交换过程需要保证不抛出异常,这样从对象副本的生成到事务处理完毕的过程中即使抛出异常也不影响对象的状态,实现了强异常安全保证。程序应至少提供基本保证,关键过程应实现强保证,与异常机制相关的过程,如析构函数、资源回收函数等,则应实现不抛异常保证。
2024-09-27 18:17:38
863
原创 一文讲通 C++ 所有初始化方法
在各种编程语言中,初始化都是非常重要的步骤,用于确保对象在使用前具有确定的初始状态。C++ 提供了多种初始化方法,每种方法都有其特定的使用场景和注意事项。综上所述,C++ 的初始化方法各有特点和使用场景,开发者在选择初始化方法时需要根据具体情况谨慎考虑,并注意避免常见的错误和陷阱。
2024-08-16 10:05:18
1749
原创 C++ 异常安全(四):RAII — 核心资源管理方案
(Resource Acquisition Is Initialization,资源获取即初始化)是 C++ 核心资源管理方案,也是保障异常安全编程的核心模式。RAII 的核心思想是将资源的生命周期与拥有该资源的对象的生命周期绑定,通过利用对象的构造函数和析构函数来自动管理资源,确保资源在使用完毕后能够正确释放,从而避免内存泄漏和其他资源管理错误。
2024-08-12 09:47:10
1088
原创 详解 C++ 移动构造函数和移动赋值运算符
移动构造函数和移动赋值运算符是 C++11 标准引入的特性,用于优化资源管理和提升性能,特别是在处理临时对象或需要复制大量数据时,也是现代 C++ 的重要特性。
2024-08-12 09:17:52
414
原创 C++ 异常安全(三):noexcept 关键字的关键作用
表明函数不会抛出异常,编译器在生成可执行程序时可以做出一些优化。例如,编译器可能减少或省略用于异常处理的代码,如栈回退(stack unwinding)的准备代码,从能减少运行开销,而且对于不会抛出异常的代码,其执行顺序可以被调整,某些步骤也可以被省略,以便提高运行效率。时,表示不会抛出任何异常,标记为 noexcept(false) 时,表示会抛出异常,便于开发者理解函数的异常安全性。关键字提高了代码可读性,明确标示函数是否会抛出异常,使开发者对可能抛出异常的代码及时作出正确处理,保障异常安全。
2024-08-02 17:14:44
627
原创 C++ 中的正号(+)到底有什么用?
在 C++ 中,正号(+)作为负号(-)的对称一元运算符,看起来好像有些多余,但实际另有玄机!lambda 表达式、数组、字符串字面量等可以转为指针,用正号转换可能是最简练的写法。其中,f1 是一个函数,f2 是函数指针,f2 可以被赋予新的值,f1 不可以。指针是无所谓正负的,所以 C++ 的这条特性显然是有意这么设计的。会被实例化成两个不同的函数,如果用正号将字符串字面量转为。这便是一元正号在 C++ 中的特殊功能,更多编程问题请参见《的类型是不一样的,一个是。
2024-08-01 17:15:23
289
原创 详细总结 C++ 运算符重载的注意事项
C++ 运算符重载是一种强大的特性,这种特性允许开发者为已存在的运算符赋予新的含义,以适应特定数据类型的需求,也是泛型编程的重要基础。运算符重载应保持运算符原有的基本含义,避免引起混淆。例如,重载加法运算符时,应确保其结果与常规加法操作相符。某些运算符,如成员访问运算符、指针访问运算符(用于指针)、作用域解析运算符、三目运算符?等,是不允许重载的。运算符重载可以通过成员函数或友元函数实现。成员函数形式重载时,左侧操作数必须是自定义类型。
2024-07-31 09:13:07
393
原创 C++ 异常安全(二):try-catch 语句的注意事项
C++ 的try-catch语句用于处理异常。当在try块中的代码抛出一个异常时,程序会立即跳出try块,并查找与之匹配的catch块来执行。以下是使用try-catch。
2024-07-30 09:24:48
670
1
原创 详解 C/C++ 全局对象注意事项
这意味着如果一个全局对象的析构依赖于另一个全局对象的状态,那么需要特别注意析构函数的执行顺序,以避免出现依赖的对象已经被析构而导致的问题。因此,必须确保全局对象的构造函数不依赖于任何在构造函数执行时尚未初始化的其他全局对象或静态变量。:虽然全局对象可以在整个程序中方便地访问和共享数据,但过度使用全局对象可能导致代码的可读性和可维护性下降。因此,应谨慎使用全局对象,并尽量将其使用范围限制在必要的范围内。:全局对象具有静态存储期,这意味着它们在程序的整个运行过程中都存在,而不是在创建它们的函数返回时就被销毁。
2024-07-29 09:36:07
341
原创 C++ 异常安全(一):盘点那些不应抛出异常的函数
在 C++11 及以后的标准中,移动构造函数和移动赋值运算符不应抛出异常,这是因为移动操作通常比复制操作更快,且不会抛出异常,编译器可以利用这一点来优化代码,例如通过消除不必要的临时对象。在某些特定上下文中,如异常处理过程中(catch 块)或异常类自身的成员函数中,除非是有意重新抛出异常,否则也不应抛出异常,以保持程序的异常安全状态。析构函数负责清理对象占用的资源,如果析构函数在异常处理过程中被调用(例如在栈展开时),它抛出的新异常会与当前处理的异常冲突。总之,在设计函数时,应仔细考虑是否应该抛出异常。
2024-07-26 15:50:15
581
原创 C/C++ 浮点运算相关要点和注意事项
总地来说,C/C++中的浮点运算需要特别注意精度、比较方法、性能和测试。开发者需要了解浮点数的表示和特性,并采取相应的措施来确保浮点运算的正确性和效率。浮点运算是复杂且需要特别注意的领域。由于浮点数的表示方式和精度限制,进行浮点运算时可能会遇到一些问题。6. 浮点数和整数之间的转换。8. 浮点数的打印和读取。10. 浮点运算的测试。4. 浮点运算的性能。
2024-07-24 09:21:56
486
原创 C/C++ #include 指令注意事项
指令是一个预处理器指令,用于在编译时将指定的文件内容包含到源文件中。这样可以确保头文件只被包含一次,避免重复定义和编译错误。指令在项目中的正确使用,从而提高代码的质量和可维护性。通过遵循这些注意事项,可以确保。在 C/C++ 中,
2024-07-23 09:15:01
486
原创 C++ 特殊成员函数的注意事项
在 C++ 中,特殊成员函数指的是编译器在某些特定情况下会自动生成的成员函数,包括默认构造函数、析构函数、拷贝构造函数、拷贝赋值运算符、移动构造函数和移动赋值运算符。总之,了解和正确使用C++中的特殊成员函数对于编写高效、可维护的代码至关重要。在设计类时,应仔细考虑是否需要显式定义这些函数,以及如何正确实现它们。了解并正确使用这些特殊成员函数对于编写高效、可维护的 C++ 代码至关重要。
2024-07-23 09:03:15
923
原创 C++ 语言标准详解
《安规集》正是一套 C++ 标准的导读资料,全称《360 安全规则集合》。众所周知,学习者不宜直接阅读语言标准文档,否则会迷失在繁杂的细节之中,对此《安规集》应运而生,为读者深入学习语言标准提供指引。
2023-11-10 15:53:57
118
原创 详解编程语言之发展趋势
近十年来,互联网发生了翻天覆地的变化。新的联网方式、新的通讯方式,乃至新的支付、交易方式深刻地影响了人们的生活,在浪潮的冲击之下,传统编程语言经受住了考验,并焕发了新的生机,同时也涌现出了很多优秀的新型编程语言。
2022-10-18 16:09:32
2142
原创 详解 C/C++ 各大编程规范
详解 Google C++ Style Guide、C++ Core Guidelines、MISRA 以及腾讯、华为、360 等各大 C/C++ 编程规范
2022-03-17 15:41:22
3561
转载 详解 C++ Undefined Behavior
梳理了 C++ ISO 标准中声明的未定义行为成因,并给出详细解说和示例代码以及应对措施,供开发者参考,也为代码审计和 Code Review 提供指导意见。
2022-03-15 11:06:21
742
原创 360 C++ 编程规范
《安全规则集合》,简称《安规集》,是一部面向安全编程的实用指南,由360质量工程部编著,指导过安全卫士、鲁大师等项目的代码编写工作。
2021-12-15 13:50:37
2562
A PATH TOWARD SECURE AND MEASURABLE SOFTWARE
2024-08-16
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人