Dereference void pointer help, xxgdb help please 
Author Message
 Dereference void pointer help, xxgdb help please

I have some code that uses a linked list and a union (for an interpreter
Im writing) to hold user entered variables.  Everything works, but the
actual return data. As an example (I dont want to clutter this up with
all my code):

int getvar(char *name, void **data)
{
    blah...
    /*   intPtr is a pointer to an integer,  pointing to a previously
allocated data area (malloc)  */
    *data = vartemp->intPtr;

Quote:
}

int main(void)
{
    blah...
    void *data;

    createvar("TEST");
    assignvar("TEST", 12);
    getvar("TEST",  data);

    printf("\nTEST = %d\n", **(int *)data);

Quote:
}

Now here's the weird part.   In xxgdb, I can type "display **(int
*)data" and I get the value I am assigning to this
"variable" named TEST.   But  the gcc compiler will not compile the
above as-is.  It says something about
"Invalid type argument 'unary *'" .  Why will xxgdb allow this syntax,
gcc will not, and what do I need to do to fix this?  For
those who'd like to actually try it, attached is full source.  Please
help!

[ vars3.c 4K ]
/*
        This code conceived and written by Bill White 7/21/00, modified for
        use in openrpg3 by Scott Hutter

        A special thanks to Bill on this one - I had a heck of a time trying
        to assign a value to a data area referenced by a void pointer. This
        was the solution we needed.
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/* union of possible variable data memory pointers */
union u_datapointer
{
        int* intPtr;
        float* floatPtr;
        char* stringPtr;

Quote:
};

/* data types enumeration */
typedef enum {INT_TYPE, FLOAT_TYPE, STRING_TYPE} DATA_TYPE;

/* node in a linked list of variable declarations (symbol table) */
struct vartype
{
        char name[12];                                  /* Name of the variable                          */
        int index;                                      /* For arrays, this is the index of the variable */
        DATA_TYPE type;                                 /* The datatype.                                 */
        int length;                                     /* Length of variable                            */
        union u_datapointer data;                       /* A pointer to the actual data area             */
        struct vartype *nextNode;                       /* Pointer to the next variable in the list      */

Quote:
};

struct vartype *varhead;

void initvars (void)
{
        /* Set up inital node, which will be at the bottom of the list, pointing to NULL */

                varhead = (struct vartype *) malloc(sizeof(struct vartype));
                varhead->nextNode = NULL;

Quote:
}

int createvar(char* varname, DATA_TYPE vartype, int varlength, int varelements)
{
        /*  Allocate space for the new variable   */

                struct vartype *newvar;
                newvar = (struct vartype *) malloc(sizeof(struct vartype));

        /*  Put this new variable at the top of the variable list  */

                newvar->nextNode = varhead;
                varhead = newvar;

        /*  Set the variable descriptor info  */

                strcpy(newvar->name, varname);
                newvar->type = vartype;
                newvar->length = varlength;

        /*  Allocate memory for the variable, depending on type  */

                switch(vartype) {
                        case INT_TYPE:
                                newvar->data.intPtr = (int*) malloc(sizeof(int)* varlength);
                                break;
                        case FLOAT_TYPE:
                                newvar->data.floatPtr = (float*) malloc(sizeof(float)* varlength);
                                break;
                        case STRING_TYPE:
                                newvar->data.stringPtr = (char*) malloc(sizeof(char)* varlength);
                                break;
                }

        return 0;

Quote:
}

int getvar(char *varname, int varindex, DATA_TYPE *vartype, int *varlength, void **dataptr)
{
        /*  Setup temporary vartype structure for search loop  */

                struct vartype *vartemp;
                int found = 0;

                vartemp = varhead;

        /*  Search for the variable name in a loop      */

                do
                {
                        if (!strcmp(vartemp->name,varname))
                        {
                                found = 1;
                                break;
                        }

                        vartemp = vartemp->nextNode;

                } while(vartemp->nextNode != NULL);

        /*  Exit if not found                 */

                if (found == 0) return 1;

        /*  Set pointers for found variable  */

                *vartype = vartemp->type;
                *varlength = vartemp->length;

                switch(vartemp->type) {
                        case INT_TYPE:
                                *dataptr = vartemp->data.intPtr;
                                break;
                        case FLOAT_TYPE:
                                *dataptr = vartemp->data.floatPtr;
                                break;
                        case STRING_TYPE:
                                *dataptr = vartemp->data.stringPtr;
                                break;
                }

        return 0;

Quote:
}

int assignvar(char *varname, void *datavalue)
{
        /*  Setup temporary vartype structure for search loop  */

                struct vartype *vartemp;
                int found = 0;

                vartemp = varhead;

        /*  Search for the variable name in a loop      */

                do
                {
                        if (!strcmp(vartemp->name,varname))
                        {
                                found = 1;
                                break;
                        }

                        vartemp = vartemp->nextNode;

                } while(vartemp->nextNode != NULL);

        /*  Exit if not found                 */

                if (found == 0) return 1;

        /*  Set the data pointer to the data, depending on type  */

                switch(vartemp->type) {
                        case INT_TYPE:
                                *(vartemp->data.intPtr) = *((int *) datavalue);
                                break;
                        case FLOAT_TYPE:
                                *(vartemp->data.floatPtr) = *((float *) datavalue);
                                break;
                        case STRING_TYPE:
                                vartemp->data.stringPtr = strdup((const char*) datavalue);
                                break;
                };

        return 0;

Quote:
}      

int freevars ( void )
{
        /*  This function will free a11 allocated variable memory  */

        struct vartype *tempstruct;

        do {
                tempstruct = varhead;

                if(tempstruct->nextNode == NULL) break;

                varhead = varhead->nextNode;

                free(tempstruct);

        } while(1);

        free(varhead);

        return 0;

Quote:
}

/* --------------------------------------------------------------- main code */
int main()
{
        int someNumber = 12;
        int z = 0;

        DATA_TYPE vartyp = INT_TYPE;
        int varlen = 1;
        int varidx = 0;
        void *varval;

        initvars();

        createvar("INTVAR", vartyp, varlen, varidx);

        assignvar("INTVAR", &someNumber);

        getvar("INTVAR", varidx, &vartyp, &varlen, varval);  

        switch (vartyp)
        {
                case INT_TYPE:
                        z = **(int *)varval;
                        printf("\nINTVAR = %d\n", z);
                        break;
        }

        freevars();

        return 0;

Quote:
}



Wed, 08 Jan 2003 03:00:00 GMT  
 Dereference void pointer help, xxgdb help please

Quote:
>I have some code that uses a linked list and a union (for an interpreter
>Im writing) to hold user entered variables.  Everything works, but the

Are you sure ?

Quote:
>actual return data. As an example (I dont want to clutter this up with
>all my code):

>int getvar(char *name, void **data)
>{
>    blah...
>    /*   intPtr is a pointer to an integer,  pointing to a previously
>allocated data area (malloc)  */
>    *data = vartemp->intPtr;

Sounds correct to me, but what if data is NULL ?
   if (data)
   {
      *data = vartemp->intPtr;
   }
   else
   {
     /* error handling */
   }

Quote:
>}

>int main(void)
>{
>    blah...
>    void *data;

>    createvar("TEST");
>    assignvar("TEST", 12);
>    getvar("TEST",  data);

According to the definition of getvar(), you want
    getvar("TEST",  &data);

Quote:
>    printf("\nTEST = %d\n", **(int *)data);

You want

make the void pointer a pointer to int

(int*)data

dereference it

*(int*)data

cast the result to be compliant with "%d"

(int)(*(int*)data)
It's hot!

    printf("\nTEST = %d\n",(int)(*(int*)data));

Quote:
>}

Try that (you don't need so a complicated snippet as yours to demonstrate
your problem)

#include <stdio.h>

int main(void)
{
int i=1234;
void *data=&i;

   printf("\nTEST = %d\n", (int)(*(int *)data));
   return 0;

Quote:
}
>Now here's the weird part.   In xxgdb, I can type "display **(int
>*)data" and I get the value I am assigning to this
>"variable" named TEST.   But  the gcc compiler will not compile the
>above as-is.  It says something about
>"Invalid type argument 'unary *'" .  Why will xxgdb allow this syntax,

No idea. Try www.gnu.org

Quote:
>gcc will not, and what do I need to do to fix this?  For
>those who'd like to actually try it, attached is full source.  Please
>help!

Please don't post attachements to Usenet. For security reasons, they can be
removed my the news-servers and for the same reason, most of us will not
open them.

--
-hs-    Tabs out, spaces in.
CLC-FAQ: http://www.eskimo.com/~scs/C-faq/top.html
ISO-C Library: http://www.dinkum.com/htm_cl
FCLC-FAQ: http://www.isty-info.uvsq.fr/~rumeau/FAQ-FCLC/FAQ-FCLC.html
C-tips: http://jackklein.home.att.net



Wed, 08 Jan 2003 03:00:00 GMT  
 Dereference void pointer help, xxgdb help please
That worked perfectly!

Can you explain then, what is the void **data actually saying in the getvar
function definition?
Am I correct in thinking : (in a function definition)
char *string = Im receiving the address of a string (ok, character)
int *var = Im receiving the address of an integer variable

Thus...
char **string = Im  receiving the address of a pointer to a string, *not* the
address of the string itself
void **data = Im receiving the address of a void pointer, not the address the
void pointer points to

In the case of the char **string, to actually use (reference) "string" I need
to say:
strcpy(*string, "hello");

And in the case of the data pointer, I need to say:
*data = &somevariable

So now, the actual address of the void pointer  in main is now pointing to my
data, instead of la-la land. Its starting
to make sense...man its hard to follow pointers to pointers...

I guess then my question is why do I need to: (int)(*(int*)data)?  I thought
by casting
as *(int*)data, I should then be able to use it as an integer value (and
printf %d should not have
a problem with it)?

I will also need to do an (int) if I were to do an assignment such as:
z = (int)(*(int *)data);  ?

Thanks for the help



Wed, 08 Jan 2003 03:00:00 GMT  
 Dereference void pointer help, xxgdb help please

Quote:
>That worked perfectly!

>Can you explain then, what is the void **data actually saying in the getvar
>function definition?

mmm... void pointer to a void pointer ? I think void* and void*************
are strictly equivallent. Just a question of "self documentation" (void**
says to the programmer: "beware, I want a pointer to a pointer")

At this point, the real question is: "Why don't you declare the exact type
rather that a void pointer?"

Quote:
>Am I correct in thinking : (in a function definition)
>char *string = Im receiving the address of a string (ok, character)

Mmm... the address of a string is *not* a character.

Quote:
>int *var = Im receiving the address of an integer variable

Yep.

Quote:
>Thus...
>char **string = Im  receiving the address of a pointer to a string, *not*
the
>address of the string itself

Yep.

Quote:
>void **data = Im receiving the address of a void pointer, not the address
the
>void pointer points to

void pointers are used when the type is unknown (aka generic). It is useful
for callback functions (have a look to the qsort() documentation in your
C-manual)

Generally (or is it always?), a single void* is enough. It is the
responsability of the programmer to do the requiered cast (or declare and
init a local pointer of the requiered type).

Quote:
>In the case of the char **string, to actually use (reference) "string" I
need
>to say:
>strcpy(*string, "hello");

Yep.

Quote:
>And in the case of the data pointer, I need to say:
>*data = &somevariable

>So now, the actual address of the void pointer  in main is now pointing to
my
>data, instead of la-la land. Its starting
>to make sense...man its hard to follow pointers to pointers...

If you are a beginner, avoid(!) void pointers at the moment. Prefer typed
pointers, it helps the compiler to do typechecking. When you will be
familiarized with the typed pointers, you will be able to play with void
pointers.

Quote:
>I guess then my question is why do I need to: (int)(*(int*)data)?  I
thought
>by casting
>as *(int*)data, I should then be able to use it as an integer value (and
>printf %d should not have
>a problem with it)?

Mmm... there are 2 different points here.

The "%d" formatter wants an (int) cast. So:
printf("%d\n",(int)whatever);
right?

On the other hand, the correct dereferencement of data wants
*(int*)data
or
(*(int*)data)
to be sure what we are talking about (I doubt, an excess of () is safe while
the opposite is not)

Once put together, we logically have

printf("%d\n",(int)(*(int*)data));

Ok? Feel free to ask for more explanation.

Quote:
>I will also need to do an (int) if I were to do an assignment such as:
>z = (int)(*(int *)data);  ?

No, AFAIK, the implicit conversion will work in most cases[1] (if not, they
will be diagnosed by the compiler), but the casts are necessary for the
variadic functions like printf().

[1] Of course, puttig a big size into a small size can have weird side
effects, like loosing significant bits.

--
-hs-    Tabs out, spaces in.
CLC-FAQ: http://www.eskimo.com/~scs/C-faq/top.html
ISO-C Library: http://www.dinkum.com/htm_cl
FCLC-FAQ: http://www.isty-info.uvsq.fr/~rumeau/FAQ-FCLC/FAQ-FCLC.html
C-tips: http://jackklein.home.att.net



Wed, 08 Jan 2003 03:00:00 GMT  
 Dereference void pointer help, xxgdb help please

Quote:

> I have some code that uses a linked list and a union (for an interpreter
> Im writing) to hold user entered variables.  Everything works, but the
> actual return data. As an example (I dont want to clutter this up with
> all my code):

> int getvar(char *name, void **data)
> {
>     blah...
>     /*   intPtr is a pointer to an integer,  pointing to a previously
> allocated data area (malloc)  */
>     *data = vartemp->intPtr;
> }

> int main(void)
> {
>     blah...
>     void *data;

>     createvar("TEST");
>     assignvar("TEST", 12);
>     getvar("TEST",  data);

>     printf("\nTEST = %d\n", **(int *)data);

Ok you've cast data to be a pointer to int.
Now dereference it once:
   *(int *)data
and the result is an int.
Now dereference an int:
   **(int *)data
and what do you have? It does not make any sense or
in other words this is an invalid unary '*'.

Quote:
> }

> Now here's the weird part.   In xxgdb, I can type "display **(int
> *)data" and I get the value I am assigning to this
> "variable" named TEST.   But  the gcc compiler will not compile the
> above as-is.  It says something about
> "Invalid type argument 'unary *'" .  Why will xxgdb allow this syntax,
> gcc will not, and what do I need to do to fix this?  For
> those who'd like to actually try it, attached is full source.  Please
> help!

Malcolm Kay


Wed, 08 Jan 2003 03:00:00 GMT  
 Dereference void pointer help, xxgdb help please

Quote:

> Ok you've cast data to be a pointer to int.
> Now dereference it once:
>    *(int *)data
> and the result is an int.
> Now dereference an int:
>    **(int *)data
> and what do you have? It does not make any sense or
> in other words this is an invalid unary '*'.

Ok, but it seems to me (obviously Im wrong)  that "**(int*)data" should still
be a valid statement, irregardlless of the
fact that **data may not point to anything useful.  Would the proper syntax
be "*(int *)*data"?   (This is really irrelevant to the
program error now - its working fine with  the help of -hs- above in this
thread, I was just curious as
to why that syntax was invalid.


Wed, 08 Jan 2003 03:00:00 GMT  
 Dereference void pointer help, xxgdb help please

Quote:
>Ok, but it seems to me (obviously Im wrong)  that "**(int*)data" should
still
>be a valid statement, irregardlless of the
>fact that **data may not point to anything useful.  Would the proper syntax
>be "*(int *)*data"?   (This is really irrelevant to the
>program error now - its working fine with  the help of -hs- above in this
>thread, I was just curious as
>to why that syntax was invalid.

Should be

**(int**)data
or
******(int******)data

Ok?

--
-hs-    Tabs out, spaces in.
CLC-FAQ: http://www.eskimo.com/~scs/C-faq/top.html
ISO-C Library: http://www.dinkum.com/htm_cl
FAQ de FCLC : http://www.isty-info.uvsq.fr/~rumeau/fclc
C-tips: http://jackklein.home.att.net



Wed, 08 Jan 2003 03:00:00 GMT  
 Dereference void pointer help, xxgdb help please

Quote:


> >That worked perfectly!

> >Can you explain then, what is the void **data actually saying in the getvar
> >function definition?

> mmm... void pointer to a void pointer ? I think void* and void*************
> are strictly equivallent. Just a question of "self documentation" (void**
> says to the programmer: "beware, I want a pointer to a pointer")

A void ** is not a generic "pointer to pointer". I believe this is
mentioned in the FAQ.

--
Joe



Thu, 09 Jan 2003 03:00:00 GMT  
 Dereference void pointer help, xxgdb help please

Quote:


>>That worked perfectly!

>>Can you explain then, what is the void **data actually saying in the getvar
>>function definition?

>mmm... void pointer to a void pointer ? I think void* and void*************
>are strictly equivallent. Just a question of "self documentation" (void**
>says to the programmer: "beware, I want a pointer to a pointer")

That is false. A void ** is a pointer to a pointer to void, not a pointer to
*any* pointer. See the FAQ; in one part it deals directly with this
misconception.

--
Any hyperlinks appearing in this article were inserted by the unscrupulous
operators of a Usenet-to-web gateway, without obtaining the proper permission
of the author, who does not endorse any of the linked-to products or services.



Thu, 09 Jan 2003 03:00:00 GMT  
 Dereference void pointer help, xxgdb help please

Quote:


>>    printf("\nTEST = %d\n", **(int *)data);

>You want

>make the void pointer a pointer to int

>(int*)data

>dereference it

>*(int*)data

>cast the result to be compliant with "%d"

>(int)(*(int*)data)
>It's hot!

>    printf("\nTEST = %d\n",(int)(*(int*)data));

Surely the result of dereferencing an (int *) is always going to be an
int, and so the (int) cast above is redundant?

               DaveK
--
"Reality is whatever doesn't go away after you stop believing in it."
                                   -- Philip K.{*filter*}



Mon, 13 Jan 2003 03:00:00 GMT  
 
 [ 10 post ] 

 Relevant Pages 

1. Please help!!!!Please help!!!!Please help!!!!Please help!!!!Please help!!!!Please help!!!!Please help!!!!

2. Please help!!!!Please help!!!!Please help!!!!

3. Can't dereference pointer to pointer?

4. help please: void/ int func. decltns

5. Void Pointer Help

6. Assigning Void Pointer, Thanks for the Help!

7. (cast)void* Help....please!

8. Please Please Help! - pointer notation

9. help: void pointer

10. Help: initializing array of void* pointers ...

11. Help...xxgdb exit code ?

12. help with xxgdb

 

 
Powered by phpBB® Forum Software