获取结构起始的起始地址

时间:2015-10-12 00:30:55

标签: c pointers struct

struct foo {
     long a;
     float d;
     void *some_ptr;
}

struct foo *start_address(void *some_other_ptr) {
    return ((struct test *)((char *) linkfield_ptr //Don't know what to do here);
}

int main() {
     struct foo fum;
     struct foo *foo_ptr;

     foo_ptr = start_address(&fum.some_ptr);
}

foo_ptr需要是struct的起始地址,所以start_address方法基本上必须返回它。我一直在抨击这个问题一个小时左右,因为我不允许使用任何宏或外部库找到答案。对此的回答以及他们如何从指针专家那里得到答案的解释将不胜感激。

1 个答案:

答案 0 :(得分:1)

如果void* some_ptr是结构的第一个字段,则它通常具有相同的地址。

否则,通用解决方案类似于offsetof的实现,类似于:

unsigned int offset = &((struct foo*)0)->some_ptr;

complete example

#include <stdio.h>
#include <stdint.h>

struct foo
{
    int padding1;
    unsigned char padding3;
    void* ptr;
    int padding2;
};

struct foo* start_address(void* ptr)
{
    uintptr_t offset = (uintptr_t)&((struct foo*)0)->ptr;
    return (struct foo*)(ptr - offset);
}

int main(void) {
    struct foo test;
    printf("%p == %p\n", &test, start_address(&test.ptr));
    return 0;
}

这很容易想到,你将地址0视为struct foo*的地址,然后如果你试图获取该结构的任何字段的地址,你就得到了偏移量(因为你是从0开始的。