去年 9 月的一篇博文中,CISA 也曾公开敦促开发人员使用内存安全编程语言。网络与基础设施安全局、联邦调查局(FBI)、国家安全局及各盟国机构随后于 12 月发布了题为《内存安全路线图案例》(The Case for Memory Safe Roadmaps)的研究报告,其中就点名 C/C++ 存在内存安全漏洞,软件开发商应放弃使用,改用 C#、Rust、Go、Java、Python 和 Swift 等内存安全的编程语言 (MSL)。

今年 2 月底,白宫国家网络主任办公室 (ONCD) 也就此发布了一份报告,呼吁科技界主动减少网络空间的攻击面;通过改用 Rust 等内存安全编程语言、避免使用 C++ 和 C 语言等易受攻击的语言,以减少内存安全漏洞的数量来提高软件安全性。

随后,C++ 的创建者 Bjarne Stroustrup 针对白宫的这些言论进行了反驳。Stroustrup 指出了 C++ 的优势,并提到该语言最早于 1979 年设计。C++ 开发始终将安全性改进作为目标之一。“只要将 K&R 时代的 C 语言与最早的 C++ 比较,再将早期的 C++ 与当代 C++ 比较就可以看出这一点,”他说。“许多高质量的 C++ 代码采用了基于 RAII(资源获取即初始化)、容器和资源管理指针的技术,而不是传统的 C-style pointer messes。”

如何安全?

在C++中进行内存安全的编程是一个复杂但至关重要的任务。以下是一些关键的策略和最佳实践,可以帮助您提高C++程序的内存安全性:

  1. 使用智能指针
    智能指针(如std::unique_ptrstd::shared_ptr)是C++11及更高版本中引入的,用于自动管理动态分配的内存。它们通过封装原始指针并提供自动的清理机制来减少内存泄漏的风险。

  2. 避免使用裸指针
    尽量减少使用原始指针(即int*float*等),因为它们不提供任何形式的内存管理或安全性。如果必须使用原始指针,请确保您完全理解其生命周期和所有权模型。

  3. 使用容器
    C++标准库提供了多种容器(如std::vectorstd::liststd::map等),它们内部实现了内存管理,并提供了安全的接口来访问和操作数据。使用容器可以减少手动管理内存的需求。

  4. 遵循RAII原则
    RAII(Resource Acquisition Is Initialization)是一种管理资源(包括内存)的惯用法。它通过在对象的构造函数中分配资源并在析构函数中释放资源来确保资源的正确管理。

  5. 避免使用mallocfree
    在C++中,应尽量避免使用C风格的内存分配函数(如mallocfree)。相反,应使用newdelete(或更好的是,使用智能指针和容器)。

  6. 使用C++11及更高版本中的特性
    C++11及更高版本引入了许多新特性,如nullptr(用于替代NULL,以避免类型混淆)、auto关键字(用于自动类型推导)、范围for循环(用于简化数组和容器的遍历)等,这些特性都有助于提高代码的安全性和可读性。

  7. 进行内存泄漏检测
    使用工具(如Valgrind、AddressSanitizer等)来检测内存泄漏和其他内存相关问题。这些工具可以帮助您识别并修复潜在的内存管理错误。

  8. 遵循良好的编程实践
    始终遵循良好的编程实践,如编写清晰的代码、进行代码审查、使用断言和异常处理来捕获和处理错误等。这些实践有助于减少错误和漏洞的发生。

  9. 了解并避免常见的内存错误
    了解常见的内存错误(如缓冲区溢出、野指针、内存泄漏等)及其原因和后果,并学会如何避免它们。

  10. 使用现代C++库和框架
    现代C++库和框架(如Boost、Qt、STL等)提供了许多高级功能和工具,这些功能和工具可以帮助您更安全地管理内存和编写高质量的代码。

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐