By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
424,950 Members | 1,032 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 424,950 IT Pros & Developers. It's quick & easy.

problem with void* in struct

P: 6
hello,
I have some problem with my project in C. I want do define a generic type of matrix. with this type I can save any kind of type(int, double, float...). but I have some errors in my code. if someone can help me I'll be very gratefull. the code is:
Expand|Select|Wrap|Line Numbers
  1. typedef struct arr{
  2.     void * p_arr;
  3. }arr;
  4.  
  5. typedef struct matrix{
  6.  
  7.     arr  * p_mat;
  8.     char* name;
  9.     int size_h;
  10.     int size_w;
  11.     int type;
  12. }matrix;
  13.  
  14.  
  15.  
  16. matrix matrix_zeroes(int i,int j) //returen pointer to matrix (ixj)
  17. {
  18.     int n=0,m=0;
  19.     matrix mat;
  20.     mat.size_h=i;
  21.     mat.size_w=j;
  22.     mat.name="matrix_zeroes";
  23.  
  24.     mat.p_mat = (arr*)(malloc(i*sizeof(arr)));
  25.  
  26.     for(n=0;n<i;n++)
  27.            (int*)mat.p_mat[n].p_arr=(int*)(malloc(j*sizeof(int)));
  28.     for(n=0;n<i;n++)
  29.        for(m=0;m<j;m++)
  30.         mat.p_mat[n].p_arr[m]=0;
  31.  
  32.     return mat;
  33. }
  34.  
  35.  
  36. void matrix_print(matrix mat)
  37. {
  38.     int m,n;
  39.     int i=mat.size_h,j=mat.size_w;
  40.         for(n=0;n<i;n++)
  41.         {
  42.             for(m=0;m<j;m++)
  43.                 printf(" %d ",(int)(mat.p_mat[n].p_arr[m]));
  44.             printf("\n");
  45.         }
  46. }
  47.  

the errors is :
error C2036: 'void *' : unknown size
error C2120: 'void' illegal with all types
error C2036: 'void *' : unknown size
error C2069: cast of 'void' term to non-'void'
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========


thanks to all,
mos
Dec 3 '10 #1

✓ answered by donbock

My first thought was to have the generic type plus an instance of each specific type and cast between them, but Sean is right -- a union is perfect. Try something like this:
Expand|Select|Wrap|Line Numbers
  1. typedef struct matrix{
  2.     char* name;
  3.     int size_h;
  4.     int size_w;
  5.     int type;
  6.     union {
  7.         int *pInt;
  8.         float *pFloat;
  9.         double *pDouble;
  10.         ...
  11.         } p_mat;
  12. }matrix;
No casts needed.

Share this Question
Share on Google+
14 Replies


100+
P: 687
There must have been line numbers along the error codes?
-> p_arr[m]
You can't index pointers of type void. Compiler has no information during compile time about the nature of data the void* points to. Cast it to some pointer type you know, e.g.
((float*)p_arr)[m]
Dec 3 '10 #2

P: 6
1) the errors
1>c:\users\reubinoff\documents\visual studio 2010\projects\test\test\test1.c(33): error C2036: 'void *' : unknown size
1>c:\users\reubinoff\documents\visual studio 2010\projects\test\test\test1.c(33): error C2120: 'void' illegal with all types
1>c:\users\reubinoff\documents\visual studio 2010\projects\test\test\test1.c(46): error C2036: 'void *' : unknown size
1>c:\users\reubinoff\documents\visual studio 2010\projects\test\test\test1.c(46): error C2069: cast of 'void' term to non-'void'

2) when I tried to cast the field in the struct the compiler say that is not a member.
what to do? how can I do generic struct
Dec 4 '10 #3

Expert 100+
P: 2,396
Take a look at Arrays Revealed for suggestions on how to handle dynamically allocated 2-dimensional arrays.
Dec 4 '10 #4

Sean Pedersen
P: 30
The compiler needs to know how much memory to allocate at run-time. Void is not a valid storage type, it's a marker to help fight against calls to random uninitialized data. Consider using a linked list which keeps track of the data type of a union on a per-object basis.
Dec 5 '10 #5

Expert 100+
P: 2,396
Sean: void may not be a valid storage type, but void* (pointer-to-void) is. The compiler has no problem allocating storage for pointer-to-void variables.

The errors reubinoff is seeing occur because he tries to dereference a pointer-to-void. That doesn't work because the compiler doesn't know what is being pointed at -- it could be anything.
Dec 5 '10 #6

Sean Pedersen
P: 30
donbock, Thank you for the helpful insight. I completely agree. I guess I got stuck in my Java rut.
(EDIT)
reubinoff, From what I've read, in
Expand|Select|Wrap|Line Numbers
  1. mat.p_mat = (arr*)(malloc(i*sizeof(arr)));
arr is of size pointer to void. You're trying to malloc memory of size pointer. (I use new but anyways.) And then cast it to arr. But its size again is a pointer. I don't really get what the code is supposed to do without some implementation example, to be honest.
Dec 5 '10 #7

P: 6
sean,
first thanks for the reference.
second, I want to create a function that can create a matrix. the function need to be a generic function that recieve IXJ and type (1=int,2=flaot...). thae function return a pointer to the matrix in the type that it request to. e.g. : mat matrix=matrix_zeroes(i,j,1 /*1=int*/);
in the function there is a switch statement. in the type =1 the matrix will be int , 2 it will be float ...
here I tried to implement only the int type. if this work I'll broad it to any type.
thanks again.
Dec 5 '10 #8

Expert 100+
P: 2,396
Write code that is customized for each type that you need to support. Once you get that code working, all you need is a wrapper function that looks at the type argument and calls the appropriate type-specific functions. This will allow you to separate the difficulty of getting the matrix arrays working from the difficulty of writing a generic function.
Dec 5 '10 #9

P: 6
but I have only 1 typedf structure that define matrix?
Dec 5 '10 #10

Expert 100+
P: 2,396
Ok ... then create more typedef structures: one for the void* (the one you already have), one for int*, one for float*, etc. (The new typedefs and the corresponding specific-type functions can all be file-local rather than global.)
Dec 5 '10 #11

P: 6
hi donbock,
how can I make 1 type(matrix) with 3 typedefs?
as I heard it's very common to use the void*,for generic function. if you can give me a good example I'll be very gratefull.
I think that my typedef not correct, but the design is right. but I have open mind to change it.
10X
Dec 6 '10 #12

Sean Pedersen
P: 30
I was thinking a union would be perfect.
Dec 6 '10 #13

Expert 100+
P: 2,396
My first thought was to have the generic type plus an instance of each specific type and cast between them, but Sean is right -- a union is perfect. Try something like this:
Expand|Select|Wrap|Line Numbers
  1. typedef struct matrix{
  2.     char* name;
  3.     int size_h;
  4.     int size_w;
  5.     int type;
  6.     union {
  7.         int *pInt;
  8.         float *pFloat;
  9.         double *pDouble;
  10.         ...
  11.         } p_mat;
  12. }matrix;
No casts needed.
Dec 6 '10 #14

P: 6
perfect!
thanks.
Dec 8 '10 #15

Post your reply

Sign in to post your reply or Sign up for a free account.