爱心编程

 

唉, 现在真是爱心泛滥的年代啊, 怎么连编程也跟爱心挂上钩了?
呵呵, 说真的,在编程的时候不妨也付出点爱心啦,因为你的爱,可以让它们更坚强!

下面,我们来看看采取点什么爱心行动:


杜绝内存操作越界

内存越界是程序的主要杀手之一,不管是读越界还是写越界,都是致命性的。
而且,很多内存越界造成的错误是随机的,很难查!所以在编程时的时候一定要小心,
对传入参数,边界值一定要严格检查。
下面的数组声明很好的说明了内存越界的危害:
type1 a;     // 如果b的下标为0xFFFFFFFF (-1), 变量a会被破坏
int   b[16];  // 注意数组下标是有符号的
type2 c;     // 如果b的下标超过15的话,变量C会被破坏

为指针做好初始化
指针没有被初始化的话, 它的值是不确定的,对未初始化的指针做读写操作,
结果是不确定的,有可能程序马上崩溃,抛出异常指令,也有可能程序不崩溃,
但却得到了莫名奇妙的错误。

 

不要操作野指针
内存指针被free后就是孤魂野鬼了,你不清楚它什么时候重新投胎,如果你还在继续
使用它的话,无论是有意还是无意的,都会为此付出不可预料的代价。
void cleanup(type1* ptr)
{
   free(ptr);
   ...
   ptr->a = 0;
}

 

避免非法的栈操作
在为函数传递指针参数的时候,一不小心,往往传错了数据类型,就很有可能引起栈操作非法。
void GetType(int *type)
{
    ...
    *type = (int)0xCB00;
}

void FooTest()
{
    char type;
    //传入的参数是指向1字节的指针, 在GetType里却赋予了2个字节的值, 这就破坏了栈空间
    GetType(&type);
}

 

不要返回指向局部变量的指针
局部变量是栈分配的,函数执行完毕就无效了,你还想把它返回给上层函数的话,是得不到你想要的结果的。
一个经典的例子如下,好多地方的面试题都用过:
char* GetString()
{
    char str[] = "Hello world!";
    ...
    return str;
}

int main()
{

  printf("%s\n", GetString());
  return 0;
}

 

小心指针运算
定义一个指针type1 *p, p指向 0x1234的话,
想当然p+1就指向0x1235了,其实除非p指向的type1是1个字节类型的,
否则就是错的, 正确答案应该是p+1指向0x1234 + sizeof(type)


库和头文件要同步更新
这中错误往往发生在双方合作开发的时候,一方利用另一方的开发包进行开发,
但提供的开发包中头文件和库文件不一致,就会引起错误。


用好sizeof
sizeof比较常用,但新人往往会用错。
char* str = "12345678";
sizeof(str) = 9, 因为包含了'\0';
而strlen(str) = 8
在声明数组的时候, sizeof可以用来做下标,比如:
#define _FORMAT  "yyyy:mm:dd"
char data[sizeof(_FORMAT)]; // 声明了一个11个字节的数组
数组作为函数参数的时候,函数里面用sizeof得到的值是指针的长度, 而不是数组的大小。
void foo(int a[16])
{

   // 打印的结果是4,而不是16, 原因是因为传递数组参数时,数组会退化成指针 
   printf("size=%u\n", sizeof(a));
}

...

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值