Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
344 views
in Technique[技术] by (71.8m points)

c - How can I get/set a struct member by offset

Ignoring padding/alignment issues and given the following struct, what is best way to get and set the value of member_b without using the member name.

struct mystruct {
    int member_a;
    int member_b;
}
struct mystruct *s = malloc(sizeof(struct mystruct));

Put another way; How would you express the following in terms of pointers/offsets:

s->member_b = 3;
printf("%i",s->member_b);

My guess is to

  • calculate the offset by finding the sizeof the member_a (int)
  • cast the struct to a single word pointer type (char?)
  • create an int pointer and set the address (to *charpointer + offset?)
  • use my int pointer to set the memory contents

but I get a bit confused about casting to a char type or if something like memset is more apropriate or if generally i'm aproching this totally wrong.

Cheers for any help

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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
", s->member_b);
    return 0;
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...