Thread: Void pointers losing their marbles

  1. #1
    Registered User
    Join Date
    Apr 2006
    Posts
    7

    Void pointers losing their marbles

    Ahoy there.

    A part of my attempts to replicate C++ style OO, I have needed to create an array of "Catalogue" Structs, which include a void pointer and a tag which tells me what type of struct the void pointer points to. This is done so that I may keep structs of different types in the same array, and then downcast them later to use their fields.

    Now, the problem I have is this. After casting the newly created and initialized struct to a void pointer and assigning it to my "Catalogue" struct. Afterwards however, when I downcast the pointer to its original type, it has reset all the values the old struct contained to default values.

    I have tested it out by, after inititializing the values of the intial struct and assigning it to the void pointer in the "Catalogue", immediately downcasting the pointer again and dereferencing the variables it contains and then printing them to the screen. I can see immediately as soon as I downcast it back to its original struct pointer type that the variables it used to contain have been set to NULL or 0.

    The memory allocation and assignment code in generic form is listed below:

    Code:
    SomeStruct *structpointer = (SomeStruct*)malloc(sizeof(SomeStruct));
    
    /*cataloguepointer is a pointer to a struct type CatalogueStruct, declared in the header*/
    
    cataloguepointer[ cataloguecounter] = (CatalogueStruct*)malloc(sizeof(CatalogueStruct));
    
    structpointer->var = inVar;
    
    cataloguepointer[ cataloguecounter]->voidpointer = (void*)structpointer;
    cataloguepointer[ cataloguecounter]->tag = "StructPointer";
    
    /*Now trying to downcast and dereference*/
    
    printf("Variable in Catalogue is %d\n", (((StructPointer*)(cataloguepointer[ cataloguecounter]))->var);
    Now I honestly do not know why the variables contained within the struct pointer are reset after it has been cast to void. Does anybody have an idea of what I am doing wrong in this casting? Any help would be much appreciated :P

  2. #2
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    The whole idea of downcasting here is wrong. When you do that you're bound to lose some data.

    If you really wanted to simulate some basic C++ OO, you should have a struct containing another struct with the data inside, that way you can reference the data somewhat convieniently without casting too much.

    Also, search the web. You'll find some interesting stuff about this topic.

  3. #3
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    I, and perhaps others, find it a whole heckuva lot easier if you post real code.
    Code:
    /* necessary headers (and their contents if user-defined) */
    
    /* code */
    
    int main()
    {
       /* code */
       return 0;
    }
    This simplifies everything by putting everyone on a level playing field and exponentially increasing your odds of getting a high quality answer that specifically isolates the problem and generates a response with a solution in a minimum of time, while at the same time demonstrating that you have taken the time to minimize an issue, thus showing that you are committed to working toward a solution and looking for input while at the same time not expecting everyone to be psychic.<breath />
    Last edited by Dave_Sinkula; 05-24-2006 at 10:27 PM.
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  4. #4
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Code:
    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    
    typedef enum { f_unknown, f_int, f_float, f_char, f_foo } foo_t;
    
    struct foo
    {
        foo_t type;
        void *data;
    };
    
    void fill( struct foo *f, foo_t t, void *v )
    {
        f->type = t;
        f->data = v;
    }
    
    char *lookup( foo_t f )
    {
        switch( f )
        {
            case f_int:     return "int";
            case f_float:   return "float";
            case f_char:    return "char";
            case f_foo:     return "struct foo";
            case f_unknown: break;
        }
        return "unknown";
    }
    
    char *dataof( struct foo *f )
    {
        static char buf[ BUFSIZ ];
        switch( f->type )
        {
            case f_int:     sprintf( buf, "%d", *((int*)(f->data)) ); break;
            case f_float:   sprintf( buf, "%f", *((float*)(f->data)) ); break;
            case f_char:    sprintf( buf, "%c", *((char*)(f->data)) ); break;
            case f_foo:     sprintf( buf, "%s", "not converted" ); break;
            default:        sprintf( buf, "%s", "unknown" );
        }
        return buf;
    }
    
    int main( void )
    {
        char c = 'a';
        int i = 1;
        float f = 2.34;
        struct foo o = { f_foo, NULL };
        struct foo data[4];
        size_t x;
    
        fill( data + 0, f_int, &i );
        fill( data + 1, f_foo, &o );
        fill( data + 2, f_char, &c );
        fill( data + 3, f_float, &f );
        
        for( x = 0; x < sizeof data / sizeof data[0]; x++ )
        {
            printf( "data[ %d ].type is \'%s\', and data[ %d ].data is %s\n",
                x, lookup( data[ x ].type ), x, dataof( &data[ x ] ) );
        
        }
    
        return 0;
    }
    
    /*
    
    data[ 0 ].type is 'int', and data[ 0 ].data is 1
    data[ 1 ].type is 'struct foo', and data[ 1 ].data is not converted
    data[ 2 ].type is 'char', and data[ 2 ].data is a
    data[ 3 ].type is 'float', and data[ 3 ].data is 2.340000
    
    */
    Typecasting back and forth is fine. You just have to make sure you're doing it right. Here's a quick hack.


    Quzah.
    Last edited by quzah; 05-24-2006 at 10:50 PM. Reason: Color.
    Hope is the first step on the road to disappointment.

  5. #5
    Registered User
    Join Date
    Apr 2006
    Posts
    7
    Hehe thanks for the quick reply, I managed to fix the problem on my own but value your input :P. I pinned it down to some errant struct dereferencing. Anyways, in regards to the posting of the code it was meant to be more of a guideline involving the code, as actual names and such of the variables are irrelevant in this context, as I know for a fact they arent the problem. It was more of a simple outline of the logic I was using, without having to include factors that have no effect on the logic of the problem.

    Anyhow, thanks for the input, much appreciated.

  6. #6
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    > A part of my attempts to replicate C++ style OO
    Are your casts of malloc indicative of you using a C++ compiler to compile your C code which pretends to be C++ ?
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  7. #7
    Registered User
    Join Date
    Apr 2006
    Posts
    7
    Haha no, it is compiled on GCC. What I meant by trying to replicate OO is more like I am trying to transfer the OO style of thinking across to C, as OO has some really handy properties that were necessary for the program.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. How to better manage large .cpp files
    By 39ster in forum C++ Programming
    Replies: 6
    Last Post: 08-25-2008, 08:24 AM
  2. ChangeDisplaySettings - Blank?
    By Tonto in forum Windows Programming
    Replies: 13
    Last Post: 12-26-2006, 04:17 PM
  3. Pls repair my basketball program
    By death_messiah12 in forum C++ Programming
    Replies: 10
    Last Post: 12-11-2006, 05:15 AM
  4. i cannot see the mouse arrow
    By peachchentao in forum C Programming
    Replies: 6
    Last Post: 12-10-2006, 04:14 AM
  5. Quack! It doesn't work! >.<
    By *Michelle* in forum C++ Programming
    Replies: 8
    Last Post: 03-02-2003, 12:26 AM