笔记二 习题2.26有符号和无符号引出的问题
Posted 王玉成的博客
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了笔记二 习题2.26有符号和无符号引出的问题相关的知识,希望对你有一定的参考价值。
这几天没有看书。以后记得坚持。
看到讲位移和符号的关系。
其中对于嵌入式开发人员,关注的是逻辑右移和算术右移(高位如果为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 1024
char 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即可。
一个有经验的程序员,应该是在写代码时,就会有意识的规避各种潜在问题的程序员。
以上是关于笔记二 习题2.26有符号和无符号引出的问题的主要内容,如果未能解决你的问题,请参考以下文章