向C中的void指针添加一定数量的字节

时间:2018-11-14 01:42:17

标签: c

我已经在这个问题上努力了很多小时。假设您有一个将int值作为参数的函数。我需要做的是获取此int值,并将该值解释为要添加到地址的字节数:

void* foo(int size){
  node->pointer += size; //assume node->pointer is of type void*
}

上面的操作实际上是将大小* 4个字节添加到指针,因为int是4个字节。将其强制转换为(char *),即

node->pointer += (char*)size; 

这不起作用。 如何以最简单的方式做到这一点?

2 个答案:

答案 0 :(得分:2)

如果您不介意使用GCC扩展名(Pointer arithmetic on void pointers and function pointers),而实际上使用的是GCC(或Clang),则可以(或多或少)编写使用+=编写的内容:

void foo(int size)
{
    node->pointer += size; // Not standard — using GCC extension
}

它不是标准C,因此不是可移植的。从C11(ISO / IEC 9899:2011):

  
      
  • §6.2.5 Types ¶19 void类型包含一组空值;这是一种不完整的对象类型,无法完成。
  •   
  • §6.5.3.4 The sizeof and _Alignof operators sizeof运算符不得应用于具有函数类型或不完整类型的表达式,此类类型的括号名称或…
  •   
  • §6.5.6 Additive operators另外,两个操作数都应为算术类型,或者一个操作数应为指向完整对象类型的指针,另一个操作数应为整数类型。
  •   
  • §6.5.6 Additive operators对于减法,应满足以下条件之一:      
        
    • 两个操作数均具有算术类型;
    •   
    • 两个操作数都是指向兼容的完整对象类型的合格或不合格版本的指针;或
    •   
    • 左操作数是指向完整对象类型的指针,而右操作数是整数类型。
    •   
  •   
  • §6.5.16.2 Compound assignment ¶1仅对于运算符+=-=,左操作数应为指向完整对象类型的原子,合格或不合格指针,并且权利应为整数类型;或左操作数应具有原子,合格或不合格的算术类型,而右操作数应具有算术类型。
  •   

由于void类型不完整且无法完成,因此void *是指向不完整类型的指针,因此不能将voidsizeof一起使用,也不能将void *+-一起使用来进行指针算术运算,因此,您不能将void *与复合赋值+=和{ {1}}。

等效的标准C为:

-=

此代码不会返回值,比您返回的值要多(尽管您之所以会这样,是因为返回类型为void foo(int size) { node->pointer = (char *)node->pointer + size; } )。由于void *node->pointer,因此您无需强制转换为void *;这是C,并且转换是自动的。

答案 1 :(得分:0)

编写示例代码以供参考。我使用了与上述答案类似的概念。

#include <stdio.h>

struct node{
 int payload;
 void *ptr;
}*n;

void foo(int x){
 n->ptr = (char *)n->ptr +x;
}

int main(){
  n = malloc(sizeof(struct node));
  n->payload = 10; //random payload
  n->ptr = n;

  printf("%p\n", n->ptr);
  foo(2); //increment by 2
  printf("%p\n", n->ptr);
}