Pointer (computer programming)
Pointer arithmetic cannot be performed on void pointers because the void type has no size, and thus the pointed address can not be added to, although gcc and other compilers will perform byte arithmetic on void* as a non-standard extension, treating it as if it were char *.
Pointer Arith
In GNU C, addition and subtraction operations are supported on pointers to void and on pointers to functions. This is done by treating the size of a void or of a function as 1.
实际上,在我们前面的文章里说过,void* 是万能指针,但是它本身是没有宽度的,所以给它进行加减运算,甚至获取加减后的地址代表的内容,都是不安全的。虽然gcc等编译器可能会默认void*所指向的区域的宽度为1字节(也就是当成char来对待)。
#include <iostream>
#include <stdio.h>
#include <memory.h>
#include <malloc.h>
using namespace std;
int main()
{
void * ptr = (void *)malloc(10);
memset(ptr,0,10);
printf("%p %p\n",ptr, (ptr+7));
for(int i= 0;i<10;i++)
{
printf("%p %d\n",ptr+i, *(unsigned char*)(ptr+i));
}
printf("%02X\n",(unsigned char*)(ptr+7));
printf("---------------------\n");
memset((unsigned char*)ptr,0,10);
for(int i= 0;i<10;i++)
{
printf("%p %d\n",((unsigned char *) ptr)+i, *((unsigned char*)ptr+i));
}
return 0;
}
下面的输出,可以看到ptr+7和ptr的地址确实差了7字节,内容也正确。

我们再修改一下,
#include <iostream>
#include <stdio.h>
#include <memory.h>
#include <malloc.h>
using namespace std;
int main()
{
void * ptr = (void *)malloc(10);
memset(ptr,0,10);
printf("%p %p\n",ptr, (ptr+7));
for(int i= 0;i<10;i++)
{
printf("%p %d\n",ptr+i, *(unsigned char*)(ptr+i));
}
printf("%02X\n",(unsigned char*)(ptr+7));
printf("---------------------\n");
memset((unsigned char*)ptr,0,10);
*((unsigned char *)ptr+7) = 8;
for(int i= 0;i<10;i++)
{
printf("%p %d\n",((unsigned char *) ptr)+i, *((unsigned char*)ptr+i));
}
return 0;
}

虽然上述输出没问题,但是还是不建议这么使用。
参考链接:https://www.zhihu.com/question/33988670/answer/57668622

本文探讨了void*指针在C/C++中的特殊性质,指出由于void类型的无宽限制可能导致不安全的加减运算。通过示例展示了GCC的非标准行为,并强调了避免直接操作void*地址的重要性,推荐遵循标准做法以确保代码健壮性。
1207

被折叠的 条评论
为什么被折叠?



