problem with a casted pointer

R

Raj Pashwar

------------------------------- Here is my
program------------------------------------------

#include <stdioi.h>
#include <stddef.h>

typedef struct dummy{
int x,y,z;
}point;

main() {
point a = {1,2,3};
int *p = (int *)(&a + offsetof(point, y);
int *q = (int *)(&a + offsetof(point, z);
printf("%d %d",*p,*q);
}

----------------------------------------------------------
 
J

James Kuyper

------------------------------- Here is my
program------------------------------------------

#include <stdioi.h>
#include <stddef.h>

typedef struct dummy{
int x,y,z;
}point;

main() {
point a = {1,2,3};
int *p = (int *)(&a + offsetof(point, y);
int *q = (int *)(&a + offsetof(point, z);
printf("%d %d",*p,*q);
}

The behavior of your program is undefined. To explain why, it's easier
if I introduce two new objects:

point array[8];
point *pp = array;

Also, I will assume, in order to make my explanation more concrete, that
we're using an implementation where sizeof(int)==2, and puts no padding
in struct dummy. Then sizeof(point) == 6, offsetof(point,y)==2, and
offsetof(point, z)==4.

When you add an integer N to a pointer, it shifts that pointer by a
large enough amount memory to store N copies of the thing it points at.
Therfore, while pp currently points at array[0], pp+offsetof(point,y)
points at p[2]. pp+offsetof(point,z) points at array[4]. If converted to
(int*), those pointers would point at the 'x' members of those structures.

For the purposes of this rule, a single object is treated as an array of
length 1. Therefore, &a+offsetof(point,y) would, in principle, point at
a memory location that hasn't necessarily been reserved for use by your
program. That's why the behavior of your program is undefined.

To get the results you desire, you need to use:

int *p = (int*)((char*)&a + offsetof(point, y));

Since the sizeof(char)==1, adding N to a char* pointer moves it forward
by N bytes, which is what you are trying to do.
i ran this program on DevC++ 4.9.9.2 and i'm getting some garbage
values as output!

That's one of the plausible results from attempting to read memory that
you're not supposed to be reading.
 
B

Ben Bacarisse

Raj Pashwar said:
------------------------------- Here is my
program------------------------------------------

#include <stdioi.h>
#include <stddef.h>

typedef struct dummy{
int x,y,z;
}point;

main() {
point a = {1,2,3};
int *p = (int *)(&a + offsetof(point, y);
int *q = (int *)(&a + offsetof(point, z);
printf("%d %d",*p,*q);
}

----------------------------------------------------------
---------------------------------------

my question is will *p and *q really point to (a.x) and (a.y) ?
i ran this program on DevC++ 4.9.9.2 and i'm getting some garbage
values as output!

Your question has been answered, but you might be missing a key piece of
information. You can write:

int *p = &a.y;

Now, you may know this, but if you do, I am puzzled by why you've be
trying get this same effect with offsetof. Anyway, it seemed worth
checking that you know the direct route.

Since I am posting... In most English dialects, the past participle of
the verb "to cast" is "cast". "The die was cast." "The pointer was cast
to another type."
 
K

Keith Thompson

Raj Pashwar said:
------------------------------- Here is my
program------------------------------------------

#include <stdioi.h>

not <stdioi.h>. It's always best to copy-and-paste said:
#include <stddef.h>

typedef struct dummy{
int x,y,z;
}point;

main() {

Should be "int main(void)".
point a = {1,2,3};
int *p = (int *)(&a + offsetof(point, y);

&a is the address of a and is of type point*. If sizeof (int) == 4,
offsetof(point, y) is probably 4. Adding 4 to a point* advances the
pointer by 4 point objects, *not* by 4 bytes.
int *q = (int *)(&a + offsetof(point, z);
Likewise.

printf("%d %d",*p,*q);

You should print a newline ("\n") at the end of the line of output.
}

----------------------------------------------------------
---------------------------------------

my question is will *p and *q really point to (a.x) and (a.y) ?
i ran this program on DevC++ 4.9.9.2 and i'm getting some garbage
values as output!

Your program's behavior is undefined.

Simpler:

int *p = &a.y;
int *q = &a.z;
 
M

Morris Keesan

------------------------------- Here is my
program------------------------------------------

#include <stdioi.h>
#include <stddef.h>

typedef struct dummy{
int x,y,z;
}point;

main() {
point a = {1,2,3};
int *p = (int *)(&a + offsetof(point, y);
int *q = (int *)(&a + offsetof(point, z);
printf("%d %d",*p,*q);
}

The problem is not with the pointers which have been cast, it's with
the pointers which have NOT been cast.
Because &a has type "pointer to structure", adding an offset to it
does not produce a pointer inside that structure. If you want to do
this using offsetof, you should cast &a to type (unsigned char *), i.e.

int *p = (int *)((char *)&a + offsetof(point, y));
int *q = (int *)((char *)&a + offsetof(point, z));

Although, as others have said, it would be better in this small example
to write it simply as
int *p = &(a.y);
int *q = &(a.z);

(Note also that you don't need the "dummy" struct tag. The only reason
to name your structs this way is if you're actually going to be using
that tag, and if you're defining the structure type with a typedef, the
only reason I can think of for doing that would be if the structure
contains a pointer to its own type).
 

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

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,581
Members
45,056
Latest member
GlycogenSupporthealth

Latest Threads

Top