在C中向空指针添加一定数量的字节
我已经在这个问题上努力了好几个小时了。假设您有一个以int值为参数的函数。我需要做的是取这个int值,并将该值解释为要添加到地址的字节数:在C中向空指针添加一定数量的字节,c,C,我已经在这个问题上努力了好几个小时了。假设您有一个以int值为参数的函数。我需要做的是取这个int值,并将该值解释为要添加到地址的字节数: void* foo(int size){ node->pointer += size; //assume node->pointer is of type void* } 上面所做的实际上是向指针添加size*4字节,因为int是4字节。将其转换为(char*),即 这不管用。 如何以最简单的方式做到这一点?如果您不介意使用GCC扩展()并
void* foo(int size){
node->pointer += size; //assume node->pointer is of type void*
}
上面所做的实际上是向指针添加size*4字节,因为int是4字节。将其转换为(char*),即
这不管用。
如何以最简单的方式做到这一点?如果您不介意使用GCC扩展()并且您实际上正在使用GCC(或Clang),那么您可以使用
+=
编写(或多或少)您编写的内容:
void foo(int size)
{
node->pointer += size; // Not standard — using GCC extension
}
但它不是标准的C,因此不可移植。根据C11(ISO/IEC 9899-2011):
- :void类型包含一组空值;它是一个不完整的对象类型,无法完成
- :sizeof运算符不得应用于具有函数类型或不完整类型的表达式、此类类型的括号名称或
- :对于加法,两个操作数都应具有算术类型,或者一个操作数应为指向完整对象类型的指针,另一个操作数应具有整数类型
- :对于减法,以下其中一项应适用:
- 两个操作数都具有算术类型李>
- 两个操作数都是指向兼容完整对象类型的合格或不合格版本的指针;或
- 左操作数是指向完整对象类型的指针,右操作数是整数类型
- :仅对于运算符
和+=
而言,左操作数应为指向完整对象类型的原子指针、限定指针或非限定指针,右操作数应为整数类型;或者,左操作数应具有原子、限定或非限定算术类型,右操作数应具有算术类型-=
void
类型不完整且无法完成,因此void*
是指向不完整类型的指针,因此不能将void
用于sizeof
,也不能将void*
用于+
或-
进行指针运算,因此,您也不能将void*
与复合赋值+=
和-=
一起使用
标准C当量为:
void foo(int size)
{
node->pointer = (char *)node->pointer + size;
}
与您的代码相比,此代码不会返回值(尽管您说过会返回,因为返回类型是
void*
)。由于节点->指针
是一个无效*
,您不需要将其转换回无效*
;这是C,转换是自动的。编写示例代码供您参考。我使用了与上面回答类似的概念
#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);
}
#包括
结构节点{
有效载荷;
无效*ptr;
}*n;
void foo(int x){
n->ptr=(char*)n->ptr+x;
}
int main(){
n=malloc(sizeof(struct node));
n->有效载荷=10;//随机有效载荷
n->ptr=n;
printf(“%p\n”,n->ptr);
foo(2);//增加2
printf(“%p\n”,n->ptr);
}
尝试节点->指针=(void*)((char*)(节点->指针)+大小)代码>非常感谢!我不敢相信我忽略了把它扔回虚空@因为char*
会自动转换为void*
,所以不需要显式转换为void*
。对吗?您的标题询问如何向“void pointer”添加若干字节,但您的问题暗示您正在向指向int
的指针添加字节,其中指出“上面所做的实际上是向指针添加大小*4字节,因为int是4字节。”节点->指针的实际类型是什么?@EricPostpischil它是void*类型在Visual Studio中也可以。你是说它在一些奇怪的平台上是不兼容的吗?我的意思是C标准说它是不允许的。我还没有得到我的报价。一种是C11;还需要其他人。但是你不能确定一个不完整类型的大小,void
无法完成,要增加一个指针,你需要知道字节大小,所以…正如我所说的,我还没有准备好所有相关的引号,我需要花一两个小时才能扩展我的答案-有一些“生命”这需要生活。对不起,我误解了你关于什么是标准和什么不是标准的回答,尽管它写得很清楚<代码>节点->指针=(字符*)节点->指针+大小代码>在Visual Studio中工作,而不是其他。我已经添加了C标准中最相关的部分。既然有一种C标准的方法可以做到这一点,那么先给出答案不是更好吗?GCC扩展似乎没有增加多少价值。
#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);
}