problem with void* in struct

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • reubinoff
    New Member
    • Dec 2010
    • 6

    problem with void* in struct

    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:
    Code:
    typedef struct arr{
    	void * p_arr;
    }arr;
    
    typedef struct matrix{
    	
    	arr  * p_mat;
    	char* name;
    	int size_h;
    	int size_w;
    	int type;
    }matrix;
    
    
    
    matrix matrix_zeroes(int i,int j) //returen pointer to matrix (ixj)
    {
    	int n=0,m=0;
    	matrix mat;
    	mat.size_h=i;
    	mat.size_w=j;
    	mat.name="matrix_zeroes";
    			
    	mat.p_mat = (arr*)(malloc(i*sizeof(arr)));
    			
    	for(n=0;n<i;n++)
               (int*)mat.p_mat[n].p_arr=(int*)(malloc(j*sizeof(int)));
    	for(n=0;n<i;n++)
    	   for(m=0;m<j;m++)
    		mat.p_mat[n].p_arr[m]=0;
    
    	return mat;
    }
    
    
    void matrix_print(matrix mat)
    {
    	int m,n;
    	int i=mat.size_h,j=mat.size_w;
    		for(n=0;n<i;n++)
    		{
    			for(m=0;m<j;m++)
    				printf(" %d ",(int)(mat.p_mat[n].p_arr[m]));
    			printf("\n");
    		}
    }

    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
  • newb16
    Contributor
    • Jul 2008
    • 687

    #2
    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]

    Comment

    • reubinoff
      New Member
      • Dec 2010
      • 6

      #3
      1) the errors
      1>c:\users\reub inoff\documents \visual studio 2010\projects\t est\test\test1. c(33): error C2036: 'void *' : unknown size
      1>c:\users\reub inoff\documents \visual studio 2010\projects\t est\test\test1. c(33): error C2120: 'void' illegal with all types
      1>c:\users\reub inoff\documents \visual studio 2010\projects\t est\test\test1. c(46): error C2036: 'void *' : unknown size
      1>c:\users\reub inoff\documents \visual studio 2010\projects\t est\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

      Comment

      • donbock
        Recognized Expert Top Contributor
        • Mar 2008
        • 2427

        #4
        Take a look at Arrays Revealed for suggestions on how to handle dynamically allocated 2-dimensional arrays.

        Comment

        • Sean Pedersen
          New Member
          • Dec 2010
          • 30

          #5
          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.

          Comment

          • donbock
            Recognized Expert Top Contributor
            • Mar 2008
            • 2427

            #6
            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.

            Comment

            • Sean Pedersen
              New Member
              • Dec 2010
              • 30

              #7
              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
              Code:
              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.
              Last edited by Sean Pedersen; Dec 5 '10, 11:01 AM. Reason: i'm smarter now

              Comment

              • reubinoff
                New Member
                • Dec 2010
                • 6

                #8
                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_z eroes(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.

                Comment

                • donbock
                  Recognized Expert Top Contributor
                  • Mar 2008
                  • 2427

                  #9
                  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.

                  Comment

                  • reubinoff
                    New Member
                    • Dec 2010
                    • 6

                    #10
                    but I have only 1 typedf structure that define matrix?

                    Comment

                    • donbock
                      Recognized Expert Top Contributor
                      • Mar 2008
                      • 2427

                      #11
                      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.)

                      Comment

                      • reubinoff
                        New Member
                        • Dec 2010
                        • 6

                        #12
                        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

                        Comment

                        • Sean Pedersen
                          New Member
                          • Dec 2010
                          • 30

                          #13
                          I was thinking a union would be perfect.

                          Comment

                          • donbock
                            Recognized Expert Top Contributor
                            • Mar 2008
                            • 2427

                            #14
                            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:
                            Code:
                            typedef struct matrix{
                                char* name;
                                int size_h;
                                int size_w;
                                int type;
                                union {
                                    int *pInt;
                                    float *pFloat;
                                    double *pDouble;
                                    ...
                                    } p_mat;
                            }matrix;
                            No casts needed.

                            Comment

                            • reubinoff
                              New Member
                              • Dec 2010
                              • 6

                              #15
                              perfect!
                              thanks.

                              Comment

                              Working...