This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

void pointer to struct pointer cast

I declared a void pointer

void *ptr;

and a typedef struct named testStructure, with a member 'unsigned int a'.

Now I will cast this pointer to a struct pointer:

ptr=(testStructure*)malloc(sizeof(testStructure));

Now I try to access the member of the struct...

ptr->a=5;

...and I get an error "expression must have a pointer-to-struct-or-union type"...
Why is 'ptr' still void? It seems, a void pointer cannot be casted to any other pointer type...
How I can do this properly?
I just need ONE pointer, which can point to different structures, that means, I need to cast a void pointer...

  • It doesn't work like that!

    For a start, if you want a pointer to that structure, why don't you just define it as a pointer to that structure:

    testStructure *ptr;
    

    The type given for a variable in its declation or definition is fixed; if you declare ptr as a pointer to void, then it will always be a pointer to void.
    If you want to use it as a pointer to something else, then you have to cast it at the point that you use it.

    So the cast in your mallo statement is pointless; the cast should come when you reference the pointer:

    ptr = malloc( sizeof(testStructure) );
    

    ((testStructure*)ptr)->a = 5;
    

    You should also consider a more meaningful name for it...

  • Ok, I get it, and it works, until I added a void pointer to void pointer in the structure:

    typedef struct
    {
    int p1,p2;
    void **dynStructArray;
    } tDSA;
    
    tDSA *parent;
    

    Now i will create something similar to a tree:

    parent=malloc(sizeof(tDSA));
    parent->dynStructArray=malloc(sizeof(*(parent->dynStructArray)));
    *(parent->dynStructArray)=malloc(sizeof(tDSA));
    

    And I try to access a member of the structure 'in' the structure:
    A pointer in the structure tDSA points to an array of pointers, which one of them (for now only the first exists) points to another dynamically created structure tDSA.

    (*(struct tDSA*)(parent->dynStructArray))->p1=5; //dereferencing void pointer as tDSA pointer
    

    And it still doesn't work, because the compiler says: "incomplete type is not allowed"...

    Why is the tDSA structure incomplete? I think, it includes just two ints, and one pointer,
    so what is inclomplete...?

  • It's the same kind of mistake as the first time. As Andy said, if you want dynStructArray to be a pointer to an array of tDSA's, then why not declare it as such? It will save you many unnecessary type casts:

    struct DSA;
    
    typedef struct DSA tDSA;
    
    struct DSA
    {
    int p1,p2;
    tDSA **dynStructArray;
    };
    
    tDSA *parent;
    


    Now you allocate memory:

    parent=malloc(sizeof(tDSA));
    parent->dynStructArray=malloc(sizeof(*(parent->dynStructArray)));
    (parent->dynStructArray)[0]=malloc(sizeof(tDSA));
    


    Then you can access the only element of the array like this:

    (parent->dynStructArray)[0]->p1=5;
    

  • This term has a specific meaning in the context of the 'C' programming language - see your 'C' textbook for details!

  • What you say is all good but I'm having a similar problem casting (elegantly) a common pointer at runtime.

    I have a common kernel which uses various dll's to implement a particular sub-system determined at runtime. Each sub-system requires a different data structure; the pointer to which must be stored at the kernel level to be within scope at runtime when I malloc() the required structure space.

    I therefore want a generic (void*) pointer in the kernel. I do not want to use a specific typedef as this requires the sub-system data structure to be defined in an include that the kernel has access to (this is really my problem).

    I am trying to make each sub-system (dll) self contained so wish to keep all the data definitions with the sub-system (i.e. not available to the kernel at build time).

    So what I require is a way to declare a pointer (presumably 'void') and then assign it a structure type at runtime so I don't need to cast each access to the structure.

    Doesn't seem a big ask but I can't see anyway around not using your

    (struct*)ptr->a
    

    syntax but this will be very messy for the many hundreds of references I'm making to the structure members.

    Any other ideas?

  • But it is!

    Types are purely a compile-time, source thing - they have no meaning at runtime to the actual CPU!

    How about #define-ing a macro...?

  • You have 2 conflicting goals.
    The kernel accessing data, and you not wanting to have an understanding of what it is accessing because it is in a DLL. If the Kernel merely needs to pass the data (pointer) I suppose this works.

    Erstwhile making a macro is likely the 'cleanest' route.
    IE

    typedef struct insect
    {
     float value;
     char *name;
     uint32_t count;
    }
    insect;
    
    #define INSECT(VPTR) ((insect *)(VPTR))
    #define INSECT_VALUE(VPTR) INSECT(VPTR)->value
    #define INSECT_NAME(VPTR)  INSECT(VPTR)->name
    #define INSECT_COUNT(VPTR) INSECT(VPTR)->count
    

    etc

  • "Erstwhile (sic?) making a macro is likely the 'cleanest' route."

    Is that really the word you were looking for:

    www.dictionary.cambridge.org/define.asp

  • "I therefore want a generic (void*) pointer in the kernel. ...

    So what I require is a way to declare a pointer (presumably 'void') and then assign it a structure type at runtime so I don't need to cast each access to the structure."

    Is there a reason that each subsystem can't simply assign the 'void*' to its own subsystem-specific structure pointer and use that? No casting required.

  • Note that C and C++ differs a bit for void* pointers.