【问题标题】:Accessing a member of a structure through another member of the same structure通过同一结构的另一个成员访问结构的成员
【发布时间】:2014-11-05 20:03:13
【问题描述】:

假设我们有以下代码:

typedef struct
{
    int a1;
    int a2;
} a_struct;

int prev (int a2)
{
    int* p = &A_STRUCT-4;
    return *p;
}

int main(void)
{
    a_struct aStruct[] = {5, 10}; // Array-type initializing

    printf("aStruct.a1 = %i", prev(aStruct->a2));

    return 1;
}

我试图通过访问aStruct.a2 内存地址并取消引用它来访问aStruct.a1 的值,但是按照这种方式,它会导致u/b 和运行时复杂化。 一言以蔽之,行不通。我做错了什么?

【问题讨论】:

  • 它不可靠,但如果你打电话给prev(&aStruct->a2) 并写int prev(int *a2) { int *p1 = a2 - 1; return *p1; } 它应该可以工作。给定一个指向 prev() 的非指针参数,您无能为力。

标签: c pointers memory-management data-structures


【解决方案1】:

有两个不同的问题。首先,你传递一个字段的,而不是它的地址

其次,假设你有一个结构域的地址,你可以借助offsetof宏获得指向结构本身的指针:

int prev(int* pa2)
{
    size_t offset = offsetof(a_struct, a2);
    a_struct* p = (a_struct*)((char*)pa2 - offset);
    return p->a1;
}

....

printf("aStruct.a1 = %i\n", prev(&aStruct->a2));

【讨论】:

  • size_t offset = (int)offsetof(a_struct, a2); 我不能允许,不管它是什么。我需要手动构建宏。
  • @Corelation 看看你的编译器是如何实现offsetof宏的。
  • 不幸的是它不是。我正在一个封闭平台的 SDL 窗口运行时编码。我不能包含额外的库,语言版本是 C89。
  • @Corelation 试试这样的:#define my_offsetof(s,m) (size_t)(char*)(&(((s*)0)->m))
  • 它甚至无法编译。
【解决方案2】:

有多个错误:

typedef struct
{
    int a1;
    int a2;
} a_struct;

int prev (a_struct A_STRUCT) // <== This should be void* A_STRUCT since you are receiving an address.
{
    int* p = &A_STRUCT-4; // <== This should be (char *)A_STRUCT - sizeof(int). Read about pointer arithmetic.
    return *p;
}

int main(void)
{
    a_struct aStruct[] = {5, 10}; // Array-type initializing

    printf("aStruct.a1 = %i", prev(aStruct->a2)); // <== This should be prev(&aStruct->a2) since you are passing the address. 

    return 1;
}

【讨论】:

  • 不,修复了 prev 参数,这是我的错误。我不只是复制/粘贴我所做的事情。想提供一个简短的例子。
  • @user1952500 - sizeof(int) 看起来不正确。不能保证布局是连续的。
  • @AlexD,是否也不能保证像 struct 这样的 POD 结构?
  • @AlexD,链接指向非 POD 结构。例如,来自 wiki (fnal.gov/docs/working-groups/fpcltf/Pkg/ISOcxx/doc/POD.html) 的链接说:布局构成 POD 对象的字节是连续的 [§1.8, ¶5]。 “如果 POD-struct ... 类型具有相同数量的成员,则它们是布局兼容的,并且相应的成员(按顺序)具有布局兼容的类型”[§9.2,¶14]。如果 POD-union ... 类型具有相同数量的成员,则它们是布局兼容的,并且相应的成员(以任何顺序)具有布局兼容的类型”[§9.2,¶15]。类不是 POD 结构。跨度>
  • @user1952500 我不是说上课。我的意思是链接答案中的struct some_object。在char c 之后可能有(尽管不一定)填充。在我们的情况下,填充的可能性要小得多,但据我所知,仍然不能保证。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-12-17
  • 1970-01-01
相关资源
最近更新 更多