您现在的位置:计算机技术学习网 > 技术中心 > 编程开发 > C >

【编程好习惯】使用sizeof减少内存操作失误

来源:未知 责任编辑:智问网络 发表时间:2013-09-03 11:49 点击:

在编程过程中,在大量的情况下需要使用memset()函数对内存进行置零初始化(除了这里说的memset()其实很多函数,比如snprintf()、strncpy()等都可以借用这里谈到的方法),以下三种情况是在工作中经常在这方面碰到的错误,大部分错误是因为疏忽而造成的。
例1

char *buf [FAIP_WITHDOT_MAX_LEN+1];
memset (buf, 0, FAIP_WITHDOT_MAX_LEN + 1);

例2

#define DIGEST_LEN 17
#define DIGEST_MAX 16

char digest [DIGEST_MAX];
memset (digest, 0, DIGEST_LEN);

例3

dll_node_t *p_node = malloc (sizeof (dll_node_t));
if (p_node == 0)
return;
memset (p_node, 0, sizeof (dll_t));


下面示例了如何采用一般化的方法更正上面的三种错误。
例1修订1

char *buf [FAIP_WITHDOT_MAX_LEN+1];
memset (buf, 0, sizeof (char *) * (FAIP_WITHDOT_MAX_LEN + 1));

例2修订1

#define DIGEST_LEN 17
#define DIGEST_MAX 16

char digest [DIGEST_MAX];
memset (digest, 0, DIGEST_MAX);

例3修订1

dll_node_t *p_node = malloc (sizeof (dll_node_t));
if (p_node == 0)
return;
memset (p_node, 0, sizeof (dll_node_t));


需要思考的是,如何在工作中尽可能的避免这类“低级”错误。虽然可以通过采用code review的方式增加错误的检出率,但这种效果并不好。更为好一点的方法是程序员养成一定的编程习惯,比如采用这里将要主张的sizeof()方法就能显著地降低这类错误。下面示例了如何采用sizeof()来更正错误。
例1修订2

char *buf [FAIP_WITHDOT_MAX_LEN+1];
memset (buf, 0, sizeof (buf));

例2修订2

#define DIGEST_LEN 17
#define DIGEST_MAX 16

char digest [DIGEST_MAX];
memset (digest, 0, sizeof (digest));

例3修订2

dll_node_t *p_node = malloc (sizeof (dll_node_t));
if (p_node == 0)
return;
memset (p_node, 0, sizeof (*p_node));


这里所说的采用sizeof()规避错误的方法其背后的思想是什么呢?人的大脑是注定要出错的,如果在大脑中存有处理同一事务的大量规则或根本没有规则,那么往往在处理这一事务时更容易出错。采用memset()函数对内存初始化就属于容易出错的一类事务,因为在指定实际被初始化内存的大小时,一般化的方法是需要根据被初始化内存的上下文来决定传递给memset()函数内存大小的具体值。如果采用sizeof()来获取所需初需化内存的大小并将其固化成编程习惯,那么就不容易出错。

对于前面的第一和第二种错误,只需要将数组当作sizeof()的参数,而不用关心数组在定义时的大小到底是多少。即使因为需要而更改目标数组的大小,sizeof()仍会返回更改后的实际数组的大小,而不需要对memset()函数的调用做任何的手动更改。对于第三种错误,方法是相类似的,只不过要采用sizeof(*xxx)的形式,其中xxx是目标指针变量,比如前面第三个例子中的p_node。

注意到采用sizeof()方法的共性了吗?都是以需要初始化的目标变量作为sizeof()的参数的,而不是以目标变量的类型或是宏作为其参数,这种方式使得写出来的程序更加不容易出错。采用sizeof()方法,对于获取被初始化内存的大小简化为只有两条规则:
1)如果目标变量是一个数组,则采用sizeof(xxx)的格式获取内存大小,其中的xxx是指数组变量名,显然这个数组变量可以是嵌套在另一个数据结构中的。
2)如果目标变量是一个数据结构的指针,则采用sizeof(*xxx)获取内存大小,其中的xxx则是指数据结构指针变量名,而不是数据结构类型。

最后一个问题是,采用sizeof()会降低程序的性能吗?不会!因为sizeof()是在程序编译时由编译器进行计算并最终得出一个数字的,是一个静态的行为而不是运行时行为。

本文出自 “至简李云” 博客,请务必保留此出处http://yunli.blog.51cto.com/831344/227130

    发表评论
    请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
    用户名: 验证码:点击我更换图片
    最新评论 更多>>
    网站首页 - 友情链接 - 网站地图 - TAG标签 - RSS订阅 - 内容搜索
    Copyright © 2008-2015 计算机技术学习交流网. 版权所有

    豫ICP备11007008号-1