0

使用 OFFSETOF 宏更新结构字段的代码

#include <stdio.h>   
#define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT))   

typedef struct PodTag {    
int     i;    
double  d;    
char    c; 
}PodType;   

#pragma pack(1)
int main() 
{    
     char arr[20] = {'\0'};
     arr[0] = 0x1;
     PodType instance;
     printf("%d\n", OFFSETOF(PodType, c));   
     memset(&instance,0,sizeof(PodType)); 
     memcpy(&instance+OFFSETOF(PodType, c),&arr[0],sizeof(char));
     printf("Val of C = %d\n",instance.c); // value is not reflected
     getchar();    
return 0; 
} 

我在这里做 memcpy 。价值不体现。怎么了

memcpy(&instance+OFFSETOF(PodType, c),&arr[0],sizeof(unsigned char));

我们可以做这样的事情来更新结构字段

#define OFFSETOF_DATA(TYPE, ELEMENT,data) \
  (*((size_t)&(((TYPE *)0)->ELEMENT)) = (unsigned char)(data))  
4

2 回答 2

2

这条线引起了麻烦:

 memcpy(&instance+OFFSETOF(PodType, c),&arr[0],sizeof(char));

它将&instance作为数组的开头,并在其上添加诸如 16 之类的数字,从而访问i虚构数组的第 16 个成员的元素。

你需要使用:

 memcpy((char *)&instance+OFFSETOF(PodType, c), &arr[0], sizeof(char));

这会将正确数量的字节添加到 的字节地址&instance。请注意,演员表独立于字段char *这一事实;即使您正在访问or元素,您仍然会在那里使用演员表。ccharchar *id

#include <stdio.h>
#include <string.h>

#define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT))

typedef struct PodTag
{
    int i;
    double d;
    char c;
} PodType;

int main(void)
{
    char arr[20] = {'\0'};
    arr[0] = 0x1;
    PodType instance;
    printf("%zu\n", OFFSETOF(PodType, c));
    memset(&instance, 0, sizeof(PodType));
    memcpy((char *)&instance+OFFSETOF(PodType, c), &arr[0], sizeof(char));
    printf("Val of C = %d\n", instance.c);
    return 0;
}

示例输出(Mac OS X 10.9 Mavericks;GCC 4.8.2,64 位编译):

16
Val of C = 1
于 2013-11-08T05:37:18.110 回答
0

(TYPE*)0<< 将是一个 NULL 指针。

于 2013-11-08T05:25:30.120 回答