Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   C Programming (http://www.velocityreviews.com/forums/f42-c-programming.html)
-   -   problem with a casted pointer (http://www.velocityreviews.com/forums/t754711-problem-with-a-casted-pointer.html)

Raj Pashwar 10-08-2011 08:44 PM

problem with a casted pointer
 

------------------------------- 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!

James Kuyper 10-08-2011 09:05 PM

Re: problem with a casted pointer
 
On 10/08/2011 04:44 PM, Raj Pashwar wrote:
>
> ------------------------------- 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) ?


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.
--
James Kuyper

Ben Bacarisse 10-08-2011 09:54 PM

Re: problem with a casted pointer
 
Raj Pashwar <raj121190@hotmail.NOSPAM.com> writes:

> ------------------------------- 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."

--
Ben.

Keith Thompson 10-08-2011 09:58 PM

Re: problem with a casted pointer
 
Raj Pashwar <raj121190@hotmail.NOSPAM.com> writes:
> ------------------------------- Here is my
> program------------------------------------------
>
> #include <stdioi.h>


Typo: <stdio.h>, not <stdioi.h>. It's always best to copy-and-paste
your code.

> #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;

--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"

Morris Keesan 10-10-2011 06:29 PM

Re: problem with a casted pointer
 
On Sat, 08 Oct 2011 16:44:26 -0400, Raj Pashwar
<raj121190@hotmail.nospam.com> wrote:

>
> ------------------------------- 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).

--
Morris Keesan -- mkeesan@post.harvard.edu


All times are GMT. The time now is 12:35 AM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.