C Offsetof

M

mihirtr

Hi,
I have following structures and union

typedef struct
{
int a[100];
int b;
char *c;

}TEST_1;
typedef struct
{
int a[100];
char c[100];

}TEST_2;


union Member
{
TEST_1 test_1;
TEST_2 test_2;
};

typedef enum{
START_ID_0 = 0x2000,
START_ID_1,
START_ID_2,
START_ID_3,
START_ID_4
}SomeIdd;

typedef struct BufferTag
{
SomeId *id;
union Member *mem;
}Buffer;



In my program somehow I get pointer to "mem" in struct "Buffer". Now I
want to get value stored in "id". Is there a way. I read at multiple
places that I can use offsetof but when I try it gives by Segmentation
fault. Can you experts check this and let me know.
FOllowing is what I am doing.

#define GetMemFromBuf (out,source) \
(out) = (Buffer *) \
((char *) (source) - (offsetof(Buffer, mem)))

Following is that way I am accessing it.
Buffer *myBuff;
GetMemFromBuf (myBuff, (void *)myMem);
printf("ID = %d",(*myBuff->id));
 
M

Malcolm McLean

Hi,
I have following structures and union

typedef struct
{
int a[100];
int b;
char *c;

}TEST_1;
typedef struct
{
int a[100];
char c[100];

}TEST_2;


union Member
{
TEST_1 test_1;
TEST_2 test_2;
};

typedef enum{
START_ID_0 = 0x2000,
START_ID_1,
START_ID_2,
START_ID_3,
START_ID_4
}SomeIdd;

typedef struct BufferTag
{
SomeId *id;
union Member *mem;
}Buffer;



In my program somehow I get pointer to "mem" in struct "Buffer". Now I
want to get value stored in "id". Is there a way. I read at multiple
places that I can use offsetof but when I try it gives by Segmentation
fault. Can you experts check this and let me know.
FOllowing is what I am doing.

#define GetMemFromBuf (out,source) \
(out) = (Buffer *) \
((char *) (source) - (offsetof(Buffer, mem)))

Following is that way I am accessing it.
Buffer *myBuff;
GetMemFromBuf (myBuff, (void *)myMem);
printf("ID = %d",(*myBuff->id));
Are you sure you get a pointer to mem, and not the value of mem itself?
Ie a union Member **, not a union Member * ?
 
M

mihirtr

Hi,
I have following structures and union
typedef struct
{
int a[100];
int b;
char *c;
}TEST_1;
typedef struct
{
int a[100];
char c[100];

union Member
{
TEST_1 test_1;
TEST_2 test_2;
};
typedef enum{
START_ID_0 = 0x2000,
START_ID_1,
START_ID_2,
START_ID_3,
START_ID_4
}SomeIdd;
typedef struct BufferTag
{
SomeId *id;
union Member *mem;
}Buffer;
In my program somehow I get pointer to "mem" in struct "Buffer". Now I
want to get value stored in "id". Is there a way. I read at multiple
places that I can use offsetof but when I try it gives by Segmentation
fault. Can you experts check this and let me know.
FOllowing is what I am doing.
#define GetMemFromBuf (out,source) \
(out) = (Buffer *) \
((char *) (source) - (offsetof(Buffer, mem)))
Following is that way I am accessing it.
Buffer *myBuff;
GetMemFromBuf (myBuff, (void *)myMem);
printf("ID = %d",(*myBuff->id));

Are you sure you get a pointer to mem, and not the value of mem itself?
Ie a union Member **, not a union Member * ?

I am getting following:
Buffer received_buff;
void * my_ptr;
my_ptr = (void *)received_buff.mem;


So I have my_ptr, from here I need to get "id".

Hope I am clear.
 
T

Thad Smith

Hi,
I have following structures and union
typedef struct
{
int a[100];
int b;
char *c;
}TEST_1;
typedef struct
{
int a[100];
char c[100];
}TEST_2;
union Member
{
TEST_1 test_1;
TEST_2 test_2;
};
typedef enum{
START_ID_0 = 0x2000,
START_ID_1,
START_ID_2,
START_ID_3,
START_ID_4
}SomeIdd;
typedef struct BufferTag
{
SomeId *id;
union Member *mem;
}Buffer;
In my program somehow I get pointer to "mem" in struct "Buffer". Now I
want to get value stored in "id". Is there a way. I read at multiple
places that I can use offsetof but when I try it gives by Segmentation
fault. Can you experts check this and let me know.
FOllowing is what I am doing.
#define GetMemFromBuf (out,source) \
(out) = (Buffer *) \
((char *) (source) - (offsetof(Buffer, mem)))
Following is that way I am accessing it.
Buffer *myBuff;
GetMemFromBuf (myBuff, (void *)myMem);
printf("ID = %d",(*myBuff->id));
Are you sure you get a pointer to mem, and not the value of mem itself?
Ie a union Member **, not a union Member * ?

I am getting following:
Buffer received_buff;
void * my_ptr;
my_ptr = (void *)received_buff.mem;


So I have my_ptr, from here I need to get "id".

Hope I am clear.

It is clear from the declarations you just posted. receiver.mem is a
pointer. You code, shown above, has not initialized it, so my_ptr is
set to an uninitialized value. However, you want to use a pointer to
received_buff.mem, so
my_ptr = &received_buff.mem;

then
Buffer *myBuff;
GetMemFromBuf (myBuff, (my_ptr);
printf("ID = %d",(myBuff->id));

Note the two changes made to your code. This assumes that
received_buff.id has been initialized.
 
B

Barry Schwarz

Hi,
I have following structures and union
typedef struct
{
int a[100];
int b;
char *c;
}TEST_1;
typedef struct
{
int a[100];
char c[100];

union Member
{
TEST_1 test_1;
TEST_2 test_2;
};
typedef enum{
START_ID_0 = 0x2000,
START_ID_1,
START_ID_2,
START_ID_3,
START_ID_4
}SomeIdd;
typedef struct BufferTag
{
SomeId *id;
union Member *mem;
}Buffer;
In my program somehow I get pointer to "mem" in struct "Buffer". Now I

No you don't. See the comments below.

The apparent purpose of this macro is to find the start of a
particular Buffer structure given the address of the member mem in
that particular structure.

What is myMem? What do you think the cast is doing?

At this point in time, you do not have any object of type Buffer. You
do have a pointer but it doesn't point anywhere until the macro
expansion assigns it a value. If you insert the following before the
macro call
Buffer b;
then the macro call
GetMemFromBuf (myBuff, &b.mem);
will work and myBuff will point to b.

The code invokes undefined behavior because you never initialized id
to contain the address of an enum object (possibly because you never
had an actual struct).
I am getting following:
Buffer received_buff;
void * my_ptr;
my_ptr = (void *)received_buff.mem;

The cast is unnecessary and the code invokes undefined behavior
because mem has never been initialized with or assigned a value.
So I have my_ptr, from here I need to get "id".

You have my_ptr but it does not contain the address of mem. Malcolm's
question hits the nail on the head.

If you want the address of mem, then use
my_ptr = &received_buff.mem;


Remove del for email
 
B

Barry Schwarz

Hi,
I have following structures and union
typedef struct
{
int a[100];
int b;
char *c;
}TEST_1;
typedef struct
{
int a[100];
char c[100];
}TEST_2;
union Member
{
TEST_1 test_1;
TEST_2 test_2;
};
typedef enum{
START_ID_0 = 0x2000,
START_ID_1,
START_ID_2,
START_ID_3,
START_ID_4
}SomeIdd;
typedef struct BufferTag
{
SomeId *id;
union Member *mem;
}Buffer;
In my program somehow I get pointer to "mem" in struct "Buffer". Now I
want to get value stored in "id". Is there a way. I read at multiple
places that I can use offsetof but when I try it gives by Segmentation
fault. Can you experts check this and let me know.
FOllowing is what I am doing.
#define GetMemFromBuf (out,source) \
(out) = (Buffer *) \
((char *) (source) - (offsetof(Buffer, mem)))
Following is that way I am accessing it.
Buffer *myBuff;
GetMemFromBuf (myBuff, (void *)myMem);
printf("ID = %d",(*myBuff->id));
Are you sure you get a pointer to mem, and not the value of mem itself?
Ie a union Member **, not a union Member * ?

I am getting following:
Buffer received_buff;
void * my_ptr;
my_ptr = (void *)received_buff.mem;


So I have my_ptr, from here I need to get "id".

Hope I am clear.

It is clear from the declarations you just posted. receiver.mem is a
pointer. You code, shown above, has not initialized it, so my_ptr is
set to an uninitialized value. However, you want to use a pointer to
received_buff.mem, so
my_ptr = &received_buff.mem;

then
Buffer *myBuff;
GetMemFromBuf (myBuff, (my_ptr);
printf("ID = %d",(myBuff->id));

Note the two changes made to your code. This assumes that
received_buff.id has been initialized.

The member id is a pointer. To print the value it points to with %d,
you need to dereference it as his original code did. If you want to
print the address it points to, you need to use %p and cast it to
void*.


Remove del for email
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

Forum statistics

Threads
473,755
Messages
2,569,535
Members
45,007
Latest member
obedient dusk

Latest Threads

Top