linux c 的void *指针的加减算术运算的说明

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

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

 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值