为了我的教育目的,我想知道是否有一种替代方法,使用memcpy()将以下代码转换为字符数组?
#include <stdio.h>
#include <string.h>
typedef void (*_vfp)(void);
#define FPSZ sizeof(_vfp)
union rcast {
_vfp fp;
char fp_c[FPSZ];
} rc;
void a(void){
printf("a()\n");
}
int main(int argc, char **argv)
{
int i=0;
memset(&rc,0,FPSZ);
rc.fp=a;
for (i=0;i<FPSZ;++i)
printf("%hhx ",rc.fp_c[FPSZ-i-1]);
puts("");
printf("%p\n",a);
return 0;
}
感谢。
答案 0 :(得分:0)
最低限度地修改您的代码:
#include <stdio.h>
#include <string.h>
typedef void (*_vfp)(void);
#define FPSZ sizeof(_vfp)
void a(void){
printf("a()\n");
}
int main(int argc, char **argv)
{
int i=0;
_vfp fp = a;
char fp_c[FPSZ];
memcpy(fp_c, &fp, FPSZ);
for (i=0;i<FPSZ;++i)
printf("%hhx ",fp_c[FPSZ-i-1]);
puts("");
printf("%p\n",a);
return 0;
}
编辑:在回复评论时,这里是没有代理且没有memcpy的版本
#include <stdio.h>
#include <stdint.h>
#include <limits.h>
#include <string.h>
typedef void (*_vfp)(void);
#define FPSZ sizeof(_vfp)
void a(void){
printf("a()\n");
}
int main(int argc, char **argv)
{
int i=0;
char fp_c[FPSZ];
for (i=0;i<FPSZ;++i)
fp_c[i] = (char) (((uintptr_t) &a) >> CHAR_BIT * i);
for (i=0;i<FPSZ;++i)
printf("%hhx ",fp_c[FPSZ-i-1]);
puts("");
printf("%p\n",a);
return 0;
}
答案 1 :(得分:0)
为了我的教育目的,我想知道是否有一种替代方法,使用memcpy()将以下代码转换为字符数组?
请注意:尽管数组和指针紧密相关,但它们却是截然不同的。在许多其他差异中,您可以在强制转换运算符中使用指针类型,并将指针用作强制转换操作数,但不能在这些上下文中使用数组类型或数组。
你好像说你想要的是一个包含函数指针值的字节的char数组(而不是指针所指向的字节)。你可以通过几种方式获得它或类似的东西。最简单的方法是为指针的值创建char *
。同样,那个不是一个数组,但它可以用于许多与数组相同的方式使用:
typedef void (*_vfp)(void);
int main(int argc, char **argv)
{
int i;
_vfp fp = a;
char *cp = &fp;
for (i = 0; i < sizeof(fp); ++i) {
printf("%hhx ", cp[i]);
}
printf("\n%p\n", (void *) a);
return 0;
}
但请注意,上述代码表现出未定义的行为。 %p
字段描述符告诉printf()
相应的参数是对象指针。 C在对象指针和函数指针之间进行了区分,并没有定义在这两个类型系列的值之间进行转换的任何行为。我包括一个明确表达这种转换的演员(这可能使编译器能够注意和抱怨);您的代码会导致隐式执行此类转换。
如果你想要一个包含指针值的字节的单独数组对象(而不是指向函数的那个),那么你可以用类似的方式得到它:
int main(int argc, char **argv)
{
_vfp fp = a;
char array[sizeof(fp)];
memcpy(array, &fp, sizeof(array));
/* ... */
}
那个人使用memcpy()
,就像你问的那样。
无论如何,不需要工会。实际上,虽然基于联合的方法可能适用于您的C实现,但是从最近编写的不同联合成员读取正式表示未定义的行为。
答案 2 :(得分:0)
您正在做的是正式的未定义行为。 C语言表示联合可以包含任何不同的变量,但是您只能访问在联合中设置的变量:联合的大小足以包含其最大的成员。 at的值 大多数成员可以随时存储在union对象中。(参考:C语言规范草案 - 6.7.2.1结构和联合说明符 - 16)
因此,通过void执行指针转换既不好也不差:
intptr_t ip = (intptr_t) &a;
char *fp_c = (void *) &intptr_t;
或memcpy
:
char fp_c[FPSZ];
intptr_t ip = (intptr_t) &a;
memcpy(fp_c, &ip, sizeof(intptr_t));
所有人都会给你相同的结果:
for (i=0; i<FPSZ; i++) {
printf("%hhx ",fp_c[FPSZ-i-1]);
}
fputs("\n");