We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
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.