对于多级指针或者数组,要掌握正确的识别方法:
void* 是说: 这是一个指针,去掉一个()就是它所指向的,在这里是指向放void型的地方;
void** 是说: 这也是一个指针,去掉一个()就是它所指向的,它指向一个放void*型的地方.
结果:
main 35 databuf = 7ffdeec28060
main 36 &databuf = 0x7ffdeec27f70
11 arg = 0x7ffdeec27f70
12 arg = 0x7ffdeec27f70
13 arg val = 0x7ffdeec27f70
14 arg val = 0x7ffdeec28060
19 *argp val = 0x1234
main 39 databuf = 7ffdeec28060
28 *argp val = 0x1234
main 42 databuf = 1234
ioctl1 argp指向的是 arg地址上存的值databuf,即7ffdeec28060,则argp赋值只会改变7ffdeec28060地址上的值,不会改变7ffdeec28060地址
ioctl1 argp指向的是 arg地址,即0x7ffdeec27f70,则argp赋值,会改变0x7ffdeec27f70地址上的值,databuf会随之改变。
源代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static int ioctl1(unsigned long arg)
{
unsigned long retval = 0x1234;
printf("\n%d arg = 0x%lx\n", __LINE__, arg);
printf("%d arg = %p\n", __LINE__, (void *)arg);
printf("%d arg val = 0x%lx\n", __LINE__, (void **)arg);
printf("%d arg val = 0x%lx\n", __LINE__, *(void **)arg);
void *argp = *(void **)arg;
memcpy(argp, &retval, sizeof(unsigned long));
printf("%d *argp val = %p\n", __LINE__, *(unsigned long *)argp);
}
static int ioctl2(unsigned long arg)
{
unsigned long retval = 0x1234;
void *argp = (void *)arg;
memcpy(argp, &retval, sizeof(unsigned long));
printf("\n%d *argp val = %p\n", __LINE__, *(unsigned long *)argp);
}
int main()
{
unsigned long databuf;
printf("%s %d databuf = %lx\n", __func__, __LINE__, databuf);
printf("%s %d &databuf = %p\n", __func__, __LINE__, &databuf);
ioctl1( &databuf);
printf("%s %d databuf = %lx\n", __func__, __LINE__, databuf);
ioctl2( &databuf);
printf("%s %d databuf = %lx\n", __func__, __LINE__, databuf);
}