笔记二 习题2.26有符号和无符号引出的问题

来源:互联网 发布:华为中级网络认 编辑:程序博客网 时间:2024/04/29 14:20

这几天没有看书。以后记得坚持。

看到讲位移和符号的关系。
其中对于嵌入式开发人员,关注的是逻辑右移和算术右移(高位如果为1,就依次填充1)的差异性,一般的编译器默认的是算术右移。
我们在操作硬件时,必须使用无符号的类型。上面是概念性的理解。

但是关于有符号和无符号类型,在现实中的确会造成困扰。
分析代码在此。

我用的是64位的机器编译的,所以size_t类型是unsigned long int类型。这点与书中讲的有些区别。因为书中估计是32位的机器。
例子中的returen值是一个逻辑真,与逻辑假, 感觉是一个strcmp的实现(随手查了strcmp的讨论,得到一个有用的链接,可以认真读一下,里面有很有用的编程技巧)。但是最后的结果,只能判断两个字符串长度是否一致。并不知道谁的长度长。所以我写了一个例子。然后比较了两种方法的异同。
一种是return的逻辑判断结果,一种是直接显示最后的结果。
当然,书中有明显的提示,也就是返回值是size_t的问题。如果返回值为无符号,那么就很难判断了。在printf中,分别打印出了有符号和无符号,可以明显看到结果。

看到了符号数造成的差异性的问题,我们更加关注的应该是利用有符号类型造成的安全性的问题。就和书中的注解中提到了FreeBSD中的getpeername的早期实现一样。是由于利用了符号数,恶意传值引发的安全问题。这种问题叫做缓冲区溢出漏洞。是我们在编程时,要时刻注意的。代码如下:

void* memcpy(void* dest, void* src, size_t s);#define KSIZE 1024char kbuf[KSIZE];int copy_from_kernel(void *user_dset, int maxlen){    int len=KSIZE < maxlen ? KSIZE : maxlen;    memcpy(user_dest, kbuf, len);    return len;}

可以看出,参数maxlen如果为有符号的整型,传入一个负数后,len的值经过无符号转换之后,会变得异常大。后面的数据完全暴露了。。。修正挺简单,maxlen为size_t即可。

一个有经验的程序员,应该是在写代码时,就会有意识的规避各种潜在问题的程序员。

0 0
原创粉丝点击