How can I get/set a struct member by offset

The full technique:

  1. Get the offset using offsetof:

    b_offset = offsetof(struct mystruct, member_b);

  2. Get the address of your structure as a char * pointer.

    char *sc = (char *)s;

  3. Add the add the offset to the structure address, cast the value to a pointer to the appropriate type and dereference:

    *(int *)(sc + b_offset)


The approach you've outlined is roughly correct, although you should use offsetof instead of attempting to figure out the offset on your own. I'm not sure why you mention memset -- it sets the contents of a block to a specified value, which seems quite unrelated to the question at hand.

Here's some code to demonstrate how it works:

#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>

typedef struct x {
    int member_a;
    int member_b;
} x;

int main() { 
    x *s = malloc(sizeof(x));
    char *base;
    size_t offset;
    int *b;

    // initialize both members to known values
    s->member_a = 1;
    s->member_b = 2;

    // get base address
    base = (char *)s;

    // and the offset to member_b
    offset = offsetof(x, member_b);

    // Compute address of member_b
    b = (int *)(base+offset);

    // write to member_b via our pointer
    *b = 10;

    // print out via name, to show it was changed to new value.
    printf("%d\n", s->member_b);
    return 0;
}

Ignoring padding and alignment, as you said...

If the elements you're pointing to are entirely of a single type, as in your example, you can just cast the structure to the desired type and treat it as an array:

printf("%i", ((int *)(&s))[1]);

Tags:

C

Struct