发新帖本帖赏金 30.00元(功能说明)我要提问
返回列表
打印
[技术讨论]

编写内存安全C++代码的几个技巧

[复制链接]
370|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
zhanzr21|  楼主 | 2023-1-2 14:46 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
#申请原创# 如果你关注最新的软件开发相关新闻,可能听说过NSA建议每个人都使用内存安全编程语言,大公司纷纷安利新项目要使用内存安全编程语言等等。这些建议引发了嵌入式项目中应该使用什么编程语言的讨论,并为Rust程序员提供了更多的动力来高呼Rust 是未来。

内存安全编程语言可以帮助解决特定问题,并降低与内存相关的错误的可能性,但它们并非万能。程序员仍然可能遇到内存问题和错误,不管使用内存安全语言还是非内存安全语言。因此,内存安全语言仅仅是开发人员可以用来解决问题的另一种工具,关键还是要看代码如何编写。

虽然人们普遍对迁移到像Rust这样的语言感到兴奋和感兴趣,但在嵌入式项目中,存在许多挑战,例如:
  • 培训工程师并让他们快速掌握新语言所需的时间和人力成本
  • 如何迁移现有代码以及迁移现有代码涉及的时间和人力成本
  • 现有供应商工具链还普遍缺少对新语言支持

以上只是几个例子,但还有更多。虽然许多开发人员看到了一个新的时尚的开发语言和一些技巧来刷新简历为他们的下一份工作做准备,但对于许多团队来说,立即改用内存安全语言是不必要的!

如果开发人员注意他们正在做的事情并遵循行业最佳实践和流程,那么使用C/C++也可以避免内存安全语言帮助开发人员避免的许多错误。让我们来看看可以帮助开发人员提高内存安全性的几种C++技巧。这不是一个完整的列表,但它们是一个例子,说明C++不应该只是因为出现了崭新的开发语言而被扔在一边。最佳实践也可以使代码内存安全。

技巧1 –使用智能指针
导致内存问题的一个重要问题是使用原始指针。嵌入式开发人员都熟悉指针的使用。可以使用它们来指向存储地址和寄存器,有效地将数据传递给函数,等等。C和早期版本的C++中的原始指针的问题在于开发人员可以过于自由地做任何想做的事情。在许多情况下,会出现内存泄漏、访问超出范围的变量等问题。
在现代C++中,开发人员可以利用智能指针,其中包括:
  • auto_ptr(在 C++11 中已弃用)
  • unique_ptr
  • shared_ptr
  • weak_ptr

通常可以将智能指针视为封装在类中的原始指针。智能指针有多种用途。首先,unique_ptr可用于确保在指针超出范围时释放发生的任何内存分配。使用原始指针不能保证此行为,可能会导致内存泄漏。其次,智能指针也有权限概念。例如,unique_ptr阻止复制其包含的指针。只允许基础指针拥有一个所有者。如果另一个对象想要使用unique_ptr指向的资源,则必须使用移动语义来转移所有权。
使用C++的嵌入式开发人员应避免像C语言那样使用原始指针。智能指针是一种更好的做法,可以帮助防止导致错误和安全漏洞的常见内存问题。

技巧2–避免使用动态内存和堆
几十年来,避免动态内存和堆一直是基于微控制器的嵌入式系统的标准最佳实践。当然可以使用它们,在编写测试代码时完全可以.但使用它们有机会引入与内存相关的错误,如内存泄漏、碎片和其他潜在问题。
使用C++的嵌入式开发人员可以通过避免动态内存和堆来增加避免内存问题的机会。有几种不同的方法可以做到这一点。首先,开发人员应避免在嵌入式系统中使用标准模板库(STL)。STL内部实现中使用了大量动态内存分配。其次,开发人员可以禁用运行时类型信息(RTTI)。最后,禁用异常是另一种选择。异常的内存以未指定的方式分配,在大多数实现中是使用堆。
避免内存分配和使用堆可以立即消除内存泄漏、内存不足错误、堆碎片等问题。

技巧3 – RAII
如果可能,嵌入式开发人员最好不使用动态内存或堆。尽管如此,实际工程中有时不得不有所例外,有时可能会发现自己处于必须这样做的境地。当必须使用动态内存和堆时,开发人员可以通过遵循资源获取即初始化 (RAII) 技术来避免内存问题。
RAII是一种开发人员将对象的生命周期与其自己的资源联系起来的技术。这个想法很简单。如果应用程序获取资源,则对象应与调用初始化资源的构造函数的资源相关联。对象在其生存期内拥有该资源。当对象超出范围时,将执行析构函数,并释放资源以及任何分配的内存。
上文也讨论了智能指针如何在 RAII 中发挥重要作用。

技巧4 -使用静态分析工具
使用静态分析工具查找内存泄漏、线程问题、错误和其他潜在问题。许多静态分析工具都是现成免费的,文档社区都很完备,如clang,cppcheck,valgrind,当然还有付费的商业工具。

技巧5 -熟悉现代C++
C++语言中有很多功能,但实际上嵌入式软件开发人员只需要一小部分功能。你可以确定适合需求的子集,并抛弃其他所有内容。目标不是使用每种语言功能,只是使用帮助编写强大、实时嵌入式软件的语言工具。   
程序员应该密切关注对C++标准所做的更改。C++每三年更新一次。语言在不断发展,新的工具也在不断添加。安全性和内存安全至关重要,将来我们可能会看到语言在这方面的许多改进。

结语
C++不是内存安全语言;但许多功能和技术可用于编写内存更安全的代码。无论是否使用内存安全语言,开发人员都需要考虑他们在做什么以及它如何影响内存。

使用特权

评论回复

打赏榜单

21ic小管家 打赏了 30.00 元 2023-02-08
理由:签约作者奖励

相关帖子

发新帖 本帖赏金 30.00元(功能说明)我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:每天都進步

91

主题

1013

帖子

34

粉丝