大抵掌握一个技术或者知识都是这三个阶段:
不知道自己不知道;
知道自己不知道;
知道自己知道。
比较难突破的是“不知道自己不知道”的阶段,因为“不知道自己不知道”,所以才往往特别自信,觉得“老子天下第一”。基本上,本文要记录的一个小点,也是一个我从“不知道自己不知道”到“知道自己知道”的过程。
我们都知道(???),指针和整数在C语言里面是两种不同含义的:
指针:主要是为了方便引用(Dereferencing)一个内存地址, Dereferencing is used to access or manipulate data contained in memory location pointed to by a pointer。所以指针的目的其实就是为了这样的读写操作:
*p = a;
b = *p;
整数:整数是一个数值,它的主要目的是为了加减等计算、比对、做数组下标、做索引之类的。它的目的不是为了引用一个内存。指针和整数(这里主要是unsigned long,因为unsigned long的位数一般等于CPU可寻址的内存地址位数)本身是八竿子打不着的,但是它们之间的一个有趣联系是:
如果我们只是关心这个地址的值,而不是关心通过这个地址去访问内存,这个时候,内核经常喜欢用unsigned long代替指针。
我们下面来看2个不同的场景:
指针是指针?
copy_from_user(void *to,
const void __user *from,
unsigned long n);
copy_to_user(void __user *to,
const void *from,
unsigned long n);
在这2个函数里面,void __user *from,void __user *to都清楚地表明用户空间的虚拟地址是一个指针。这2个函数这样做的原因是非常清晰的,我就是要去Dereference用户空间的地址,进行内存拷贝的,所以它的目的是为了通过指针来访问内存。