繁体   English   中英

按地址访问struct成员

[英]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中不表示AB字节。 相反,它意味着AB元素,其中元素的大小由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));

...假设成员ab之间没有填充。

但是,有没有理由你不只是获得值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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM