C 语言最大难点揭秘[4]

2008-02-23 05:39:43来源:互联网 阅读 ()

新老客户大回馈,云服务器低至5折


  使这些格式元素成为您日常工作的一部分。能够使用各种方法解决内存问题:

  专用库
  语言
  软件工具
  硬件检查器

  在这整个领域中,我始终认为最有用并且投资回报率最大的是考虑改进源代码的风格。他无需昂贵的代价或严格的形式;能够始终取消和内存无关的段的注释,但影响内存的定义当然需要显式注释。添加几个简单的单词可使内存结果更清楚,并且内存编程会得到改进。

  我没有做受控实验来验证此风格的效果。假如您的经历和我相同,您将发现没有说明资源影响的策略简直无法忍受。这样做很简单,但带来的好处太多了。

  检测

  检测是编码标准的补充。二者各有裨益,但结合使用效果特别好。机灵的 C 或 C 专业人员甚至能够浏览不熟悉的源代码,并以极低的成本检测内存问题。通过少量的实践和适当的文本搜索,您能够快速验证平衡的 *alloc() 和 free() 或 new 和 delete 的源主体。人工查看此类内容通常会出现像清单 7 中相同的问题。


  清单 7. 棘手的内存泄漏

static char *important_pointer = NULL;
void f9()
{
if (!important_pointer)
important_pointer = malloc(IMPORTANT_SIZE);
...
if (condition)
/* Ooops! We just lost the reference
important_pointer already held. */
important_pointer = malloc(DIFFERENT_SIZE);
...
}


  假如 condition 为真,简单使用自动运行时工具不能检测发生的内存泄漏。仔细进行源分析能够从此类条件推理出证实正确的结论。我重复一下我写的关于风格的内容:尽管大量发布的内存问题描述都强调工具和语言,对于我来说,最大的收获来自“软的”以研发人员为中央的流程变更。您在风格和检测上所做的任何改进都能够帮助您理解由自动化工具产生的诊断。

  静态的自动语法分析

  当然,并不是只有人类才能读取源代码。您还应使静态语法分析 成为研发流程的一部分。静态语法分析是 lint、严格编译 和几种商业产品执行的内容:扫描编译器接受的源文本和目标项,但这可能是错误的症状。

  希望让您的代码无 lint。尽管 lint 已过时,并有一定的局限性,但是,没有使用他(或其较高级的后代)的许多程式员犯了很大的错误。通常情况下,您能够编写忽略 lint 的优秀的专业质量代码,但努力这样做的结果通常会发生重大错误。其中一些错误影响内存的正确性。和让客户首先发现内存错误的代价相比,即使对这种类别的产品支付最昂贵的许可费也失去了意义。清除源代码。现在,即使 lint 标记的编码可能向您提供所需的功能,但很可能存在更简单的方法,该方法可满足 lint,并且比较强键又可移植。

  内存库

  补救方法的最后两个类别和前三个明显不同。前者是轻量级 的;一个人能够容易地理解并实现他们。另一方面,内存库和工具通常具备较高的许可费用,对部分研发人员来说,他们需要进一步完善和调整。有效地使用库和工具的程式员是理解轻量级的静态 方法的人员。可用的库和工具给人的印象很深:其作为组的质量很高。但是,即使最优秀的编程人员也可能会被忽略内存管理基本原则的很任性的编程人员搅乱。据我观察,普通的编程人员在尝试利用内存库和工具进行隔离工作时也只能感到灰心。

  由于这些原因,我们催促 C 和 C 程式员为解决内存问题先了解一下自己的源。在这完成之后,才去考虑库。

  使用几个库能够编写常规的 C 或 C 代码,并确保改进内存管理。Jonathan Bartlett 在 developerWorks 的 2004 评论专栏中介绍了主要的候选项,能够在下面的参考资料部分获得。库能够解决多种不同的内存问题,以致于直接对他们进行比较是很困难的;这方面的常见主题包括垃圾收集、智能指针 和 智能容器。大体上说,库能够自动进行较多的内存管理,这样程式员能够犯更少的错误。

  我对内存库有各种感受。他们在努力工作,但我看到他们在项目中获得的成功比预期要小,尤其在 C 方面。我尚未对这些令人失望的结果进行仔细分析。例如,业绩应该和相应的手动 内存管理相同好,但是这是个灰色区域——尤其在垃圾收集库处理速度缓慢的情况下。通过这方面的实践得出的最明确的结论是,和 C 关注的代码组相比,C 似乎能够较好地接受智能指针。

  内存工具

  研发真正基于 C 的应用程式的研发团队需要运行时内存工具作为其研发策略的一部分。已介绍的技术很有价值,而且不可或缺。在您亲自尝试使用内存工具之前,其质量和功能您可能还不了解。

  本文主要讨论了基于软件的内存工具。更有硬件内存调试器;在很特别的情况下(主要是在使用不支持其他工具的专用主机时)才考虑他们。

  市场上的软件内存工具包括专有工具(如 IBM Rational® Purify 和 Electric Fence)和其他开放源代码工具。其中有许多能够很好地和 AIX 和其他操作系统一起使用。

  任何内存工具的功能基本相同:构建可执行文档的特定版本(很像在编译时通过使用 -g 标记生成的调试版本)、练习相关应用程式和研究由工具自动生成的报告。请考虑如清单 8 所示的程式。


  清单 8. 示例错误

int main()
{
char p[5];
strcpy(p, "Hello, world.");
puts(p);
}


  此程式能够在许多环境中“运行”,他编译、执行并将“Hello, world.\n”打印到屏幕。使用内存工具运行相同应用程式会在第四行产生一个数组边界违规的报告。在了解软件错误(将十四个字符复制到了只能容纳五个字符的空间中)方面,这种方法比在客户处查找错误症状的花费小得多。这是内存工具的功劳。

  结束语

  作为一名成熟的 C 或 C 程式员,您认识到内存问题值得特别关注。通过制订一些计划和实践,能够找到控制内存错误的方法。学习内存使用的正确模式,快速发现可能发生的错误,使本文介绍的技术成为您日常工作的一部分。您能够在开始时就消除应用程式中的症状,否则可能要花费数天或数周时间来调试。

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇: C/C 如何在程式中加载JPG图片?[2] - C,C ,JPG,图片

下一篇: 用VSTS代码验证工具捕获C/C 错误[1]