[英]Accessing struct member by address
考虑具有两个整数类型成员的结构。 我希望通过地址获得两位成员。 我可以成功获得第一个,但是我的第二个错误。 我相信这是垃圾价值。 这是我的代码:
#include <stdio.h>
typedef struct { int a; int b; } foo_t;
int main(int argc, char **argv)
{
foo_t f;
f.a = 2;
f.b = 4;
int a = ((int)(*(int*) &f));
int b = ((int)(*(((int*)(&f + sizeof(int))))));
printf("%d ..%d\n", a, b);
return 0;
}
我越来越:
2 ..1
谁能解释我哪里出错了?
根据C标准,第一个成员的偏移量必须始终为零; 这就是你的第一次演员工作的原因。 然而,由于填充,第二构件的偏移可能不一定等于结构的第一构件的尺寸。
此外,向指针添加数字不会向地址添加字节数:而是添加指向的事物的大小。 因此,当您将sizeof(int)
添加到&f
,会添加sizeof(int)*sizeof(foo_t)
。
如果你想自己做数学,你可以使用offsetof
运算符,就像这样
int b = *((int*)(((char*)&f)+offsetof(foo_t, b)));
这样做的原因是sizeof(char)
总是一个,正如C标准所要求的那样。
当然你可以使用&f.b
来避免手动进行数学运算。
你的问题是&f + sizeof(int)
。 如果A
是指针,并且B
是整数,那么A + B
在C中不表示A
加B
字节。 相反,它意味着A
加B
元素,其中元素的大小由A
的指针类型定义。 因此,如果您的体系结构中sizeof(int)
为4,则&f + sizeof(int)
表示“四个foo_t
s进入&f
,或者4 * 8 = 32个字节进入&f
”。
请尝试((char *)&f) + sizeof(int)
。
或者,当然, &f.a
和&f.b
相反,非常简单。 后者不仅会为你提供方便的int
指针,而且会让你免除所有这些演员阵容,同时也能明确定义和理解。 :)
表达式&f + sizeof(int)
将数字添加到foo_t*
类型的指针中。 指针算术始终假定指针指向数组的元素,并将该数字视为元素计数。
因此,如果sizeof(int)
为4,则&f + sizeof(int)
四个foo_t
结构指向f
,或者在&f
之后4*sizeof(foo_t)
个字节。
如果必须使用字节计数,这样的事情可能会起作用:
int b = *(int*)((char*)(&f) + sizeof(int));
...假设成员a
和b
之间没有填充。
但是,有没有理由你不只是获得值fb
或指针&f.b
?
你可以做&f.b
,并跳过实际的指针数学。
以下是我将如何更改int b
行:
int b = (int)(*(((int*)(&(f.b)))));
顺便说一句,当我按原样运行你的程序时,我得到2 ..0
作为输出。
这有效:
int b = ((int)(*(int*)((int)&f + sizeof(int))));
你将&f解释为指针,当你向它添加4(int的大小)时,它会将它解释为添加4个指针,这些指针是16或32个字节,具体取决于32对64拱。 如果将指针强制转换为int,则会正确地向其添加4个字节。
这是对正在发生的事情的解释。 我不确定你在做什么,但你肯定不应该这样做。 这可能会让您在对齐等方面遇到麻烦。找出struct元素偏移量的安全方法是:
printf("%d\n", &(((foo_t *)NULL)->b));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.