[comp.lang.c] Pointer Problems

gh1r+@andrew.cmu.edu (Gaurang Hirpara) (08/14/90)

Here's a problem which has been bugging me for a while now:

Ok. I have a struct, call it idiot, with some elements in it, nothing unusual.

Now, I have another struct, which contains in it a generic 
pointer (i.e. Ptr <pointername>). 
How can I make <pointername> point to idiot, AND be able to access the 
resulting pointer as a pointer to struct. My main problem is that even
if I do manage to get them to point to the same place (which is a problem
all by itself), I can't access the internal members of the struct. 

Any ideas?

~dan

cc100aa@prism.gatech.EDU (Ray Spalding) (08/15/90)

In article <8aliOrS00WBMI1UVYX@andrew.cmu.edu> gh1r+@andrew.cmu.edu (Gaurang Hirpara) writes:
>Ok. I have a struct, call it idiot, with some elements in it, nothing unusual.
>
>Now, I have another struct, which contains in it a generic 
>pointer (i.e. Ptr <pointername>). 
>How can I make <pointername> point to idiot, AND be able to access the 
>resulting pointer as a pointer to struct. My main problem is that even
>if I do manage to get them to point to the same place (which is a problem
>all by itself), I can't access the internal members of the struct. 

You should be able to use a cast, e.g:
	x = ((struct idiot *)pointername)->element;

Note that "Ptr" is not part of the C language; it's probably typedef'd
somewhere to "void *" or, to accommodate older implementations, "char *".

-- 
Ray Spalding, Technical Services, Office of Information Technology
Georgia Institute of Technology, Atlanta Georgia, 30332-0275
uucp:     ...!{allegra,amd,hplabs,ut-ngp}!gatech!prism!cc100aa
Internet: cc100aa@prism.gatech.edu

henry@zoo.toronto.edu (Henry Spencer) (08/15/90)

In article <8aliOrS00WBMI1UVYX@andrew.cmu.edu> gh1r+@andrew.cmu.edu (Gaurang Hirpara) writes:
>Now, I have another struct, which contains in it a generic 
>pointer (i.e. Ptr <pointername>). 

Uh, what's a "generic pointer"?  There is no such thing in C.

>How can I make <pointername> point to idiot, AND be able to access the 
>resulting pointer as a pointer to struct...

You have to cast the pointer to the desired type every time.  The type of
any C expression, i.e. your pointer, has to be known at compile time, and
that means you can't just use it as "pointer to whatever".  It has to be
a pointer to something specific.

Assuming you use "void *" as your underlying pointer type, the code looks
like this:

	struct foo {int a, b; } f;
	void *vp;

	vp = &f;
	printf("Here's f.a: %d\n", ((struct foo *)vp)->a);
-- 
It is not possible to both understand  | Henry Spencer at U of Toronto Zoology
and appreciate Intel CPUs. -D.Wolfskill|  henry@zoo.toronto.edu   utzoo!henry

griffith@eecs.cs.pdx.edu (Michael Griffith) (08/16/90)

In article <8aliOrS00WBMI1UVYX@andrew.cmu.edu> gh1r+@andrew.cmu.edu (Gaurang Hirpara) writes:
>Here's a problem which has been bugging me for a while now:
>Ok. I have a struct, call it idiot, with some elements in it, nothing unusual.
>Now, I have another struct, which contains in it a generic 
>pointer (i.e. Ptr <pointername>). 
>How can I make <pointername> point to idiot, AND be able to access the 
>resulting pointer as a pointer to struct. My main problem is that even
>if I do manage to get them to point to the same place (which is a problem
>all by itself), I can't access the internal members of the struct. 

I beleive that you can typecast the pointer like so:

   ((struct window *)generic_pointer)->width = 100;

or something similar. In other words, you typecast it as belonging to the
appropriate pointer type before you try to reference elements in it. You can
also define generic_pointer to be a union of your other structure types and
then access the appropriate structure type:

   union gen_ptr_type {
      struct window *window_ptr;
      struct screen *screen_ptr;
      .
      .
      .
      struct button *button_ptr;
   };

And then you could reference it like so:

   (generic_pointer.window_ptr)->width = 100;

                                      Michael Griffith
                                      griffith@eecs.ee.pdx.edu
                                      uunet!tektronix!psueea!eecs!griffith

beckmann@endor.harvard.edu (Gary Beckmann) (08/16/90)

Have you been following the "Operations on pointers to void."
discussion?  Basic idea is to use casts.

Happy Hacking
--
					Gary Beckmann

gh1r+@andrew.cmu.edu (Gaurang Hirpara) (08/16/90)

I got a variety of solutions, but perhaps I didn't state the problem clearly.
The form ((StructName *)Something)->x=100 works. 
However, the format I need is this type:

TopLevel->Secondary->Something->x=100;

i.e. I can't do the casting in the middle of the dereference. It won't let
me no matter which way I do it. Toplevel contains a pointer to
Secondary, which contains Something. Something initially points to a
void *. 
I want to be able to make it point to, say a struct StructName which has 
as one of its elements x, and be able to change that element. However,
if I allocate space for Something by casting to StructName, it still has
problems getting to x. 

Hope this makes the problem clearer.

~dan



"Yes suh! The 'yarth (i.e. Earth) is flat! Says so the Psalms, about the
four corners of the 'yarth. Now how you suppose a round thing has four
corners suh?"
  --unknown Fundamentalist to Clarence Darrow, Scopes Trial 

*****************************************************************************
* Gaurang Hirpara           | gh1r@andrew.cmu.edu        | Starwatcher      *
* "Dan" to English speakers | ncrx@drycas.club.cc.cmu.edu| Con Artist       *
* Writer, Dreamer, Spy...   | r746gh1r@vb.cc.cmu.edu     | --------------   *
*****************************************************************************

rmj@tcom.stc.co.uk (Rhodri James) (08/21/90)

In article <UamezZm00WB0EGzUo0@andrew.cmu.edu> gh1r+@andrew.cmu.edu (Gaurang Hirpara) writes:
>
>
>
>I got a variety of solutions, but perhaps I didn't state the problem clearly.
>The form ((StructName *)Something)->x=100 works. 
>However, the format I need is this type:
>
>TopLevel->Secondary->Something->x=100;
>
>i.e. I can't do the casting in the middle of the dereference. It won't let
>me no matter which way I do it. Toplevel contains a pointer to
>Secondary, which contains Something. Something initially points to a
>void *. 

Am I missing something? Shouldn't

  ((StructName *)(TopLevel->Secondary->Something))->x=100;

work? Or if all else fails you can hold the pointer to cast in a
temporary variable of type void *, such as;

   void *Tempthing;
   .
   .
   Tempthing = TopLevel->Secondary->Something;
   ((StructName *)Tempthing)->x=100;

Not very pleasant, I will admit, but it should work

Rhodri

Disclaimer: These ideas are mine, mine, all mine. The company doesn't
know that I think, never mind what I think.
-- 
* Windsinger                 * "Nothing is forgotten..."
* rmj@islay.tcom.stc.co.uk   *                    Mike Whitaker
*     or (occasionally)      * "...except sometimes the words"
* rmj10@phx.cam.ac.uk        *                    Phil Allcock

colin@array.UUCP (Colin Plumb) (08/21/90)

In article <UamezZm00WB0EGzUo0@andrew.cmu.edu> gh1r+@andrew.cmu.edu (Gaurang Hirpara) writes:
> I got a variety of solutions, but perhaps I didn't state the problem clearly.
> The form ((StructName *)Something)->x=100 works. 
> However, the format I need is this type:
>
> TopLevel->Secondary->Something->x=100;
>
> i.e. I can't do the casting in the middle of the dereference. It won't let
> me no matter which way I do it. Toplevel contains a pointer to
> Secondary, which contains Something. Something initially points to a
> void *. 

The way you've described it in english:
Toplevel points to Secondary, a structure.  (i.e. Toplevel = &Secondary)
Something is a field of Secondary. (i.e. Secondary.Something is legal)
Something is a pointer to a pointer to void. (i.e.  void ** Something)
StructName is a typedef for a structure with a field x, with numeric type.
You want to assign that field the value 100.

So you with to cast that void ** to a StructName *.
Easily done:
((StructName *)Toplevel->Something)->x = 100;

> I want to be able to make it point to, say a struct StructName which has 
> as one of its elements x, and be able to change that element. However,
> if I allocate space for Something by casting to StructName, it still has
> problems getting to x. 

I don't quite follow.  Given the above and
StructName foo;
you can do:
Toplevel->Something = (void **)&foo;
((StructName *)Toplevel->Something)->x = 100;

>Hope this makes the problem clearer.

Except for the fact that your sample code,
Toplevel->Secondary->Something->x = 100;
doesn't match the english.  This has the structure
Toplevel is a pointer to a structure, with a field "Secondary".
Toplevel->Secondary is a pointer to a strucutre with a field Something.
Toplevel->Secondary->Something is a pointer to a strucutre with a field x.
Toplevel->Secondary->Something->x is a numeric variable of some sort.

Now, if Toplevel->Secondary->Something is actually a void * (generaic
pointer), and the structure which contains x is "StructType" then you'd
cast it like so:
((struct SomeType *)Toplevel->Secondary->Something)->x = 100;

Does that clear things up?
-- 
	-Colin