我认为在gcc中,void *和char *在指针运算方面的处理方式相同,即void *“指向”内存中的单个字节,因此以下代码
void *p;
p = malloc(sizeof(void));
printf("%p %p\n",p,p+1);
确实会返回0x984a008 0x984a009
。类似地,void **指向一个指针,因此增加1实际上意味着增加4个字节(在32位OS上),即
void **p;
p = (void **) malloc(sizeof(void *));
printf("%p %p\n",p,p+1);
返回0x984a008 0x984a00c
。但是,以下代码让我感到困惑
void **p, *p1;
p = (void **) malloc(sizeof(void *));
p1 = (void **) p;
printf("%p %p\n",p1,p1+1);
因为它再次返回0x984a008 0x984a009
。这里发生了什么?
答案 0 :(得分:7)
暂时忽略void
指针算术的可能未定义行为......
p1
的类型为void *
。
您不能通过为其指定不同类型的值来更改变量的类型。 p1
将始终保持void *
。
分配给它的任何不同类型的表达式将隐式地强制转换为void *
(如果不能,则给出错误)。
因此它与第一个例子基本相同。
修改强>
据我所知,从一种指针类型转换为另一种指针类型实际上并没有做任何事情,其主要目的是进行类型检查。
指针只是一个内存地址,一个数字,所以内存看起来像:(分配后)
p1 p2
void * void** <- these types are fixed and known during compilation
------ ------
|1234| |1234| at address 1234 = the 4 bytes from malloc
------ ------
^
|
this value is the only thing that will change by assigning p1 to a different value
答案 1 :(得分:3)
您应该使用char *
而不是void *
,因为指向void
的指针是gcc扩展名。
char *p1 = /* ... */;
printf("%p %p\n", p1, p1+1);
无论点p
如何,p
上的指针算术使用char *
类型(不是char **
)。
如果你写:
char *p1 = /* ... */;
printf("%p %p\n", p1, (char**)p1+1);
指针算术使用char **
。
答案 2 :(得分:2)
使用void *
进行操作时,增量为1.当您使用void **
时,它是指针的大小。
在让您感到困惑的操作中,您的void *
强制转换为void **
的行为将被隐式恢复为void *
。就好像你这样做了:
long a, b, c;
c = a + (int) b;
您将b
投射到int
,但之后您希望使用long
进行操作,因此它会被投回。
答案 3 :(得分:1)
void指针不能递增。这是未定义的行为。
答案 4 :(得分:0)
我知道我在一年后发帖,但我碰巧遇到了这个问题,这引起了我的兴趣。
我同意@Dukeling你不能仅仅通过投射来改变变量的类型。但它似乎取决于编译器认为void
的内容。以此示例程序为例,查看结果输出。请注意,vp
和vp2
之间的唯一区别是sizeof()
的{{1}}部分。
编译于:malloc()
编译行:gcc (Debian 4.7.2-5) 4.7.2
gcc -o void_test void_test.c
提供以下输出:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv) {
void *vp, *vp2;
printf("sizeof(void) = %d\n", sizeof(void));
printf("sizeof(void *) = %d\n", sizeof(void *));
printf("sizeof(char) = %d\n", sizeof(char));
printf("sizeof(char *) = %d\n\n", sizeof(char *));
vp = (void *) malloc(sizeof(void));
vp2 = (void *) malloc(sizeof(void *));
printf("vp = %p\n", vp);
printf("vp+1 = %p\n", vp+1);
printf("vp2 = %p\n", vp);
printf("vp2+1 = %p\n", vp2+1);
return 0;
}