#1
  1. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    May 2013
    Posts
    57
    Rep Power
    0

    Bidimensional Array


    i HAVE A BIDIMENSIONAL ARRAY IN THIS FUNCTION:

    void pre_filter_Computations(double radius[][cols],double theta[][cols],int cols,int rows);

    I had an error cos' I don t know before the cols dimension. So I changed it into:

    void pre_filter_Computations(double *radius,double *theta,int cols,int rows);

    double *radius[rows][cols],*theta[rows][cols];

    But now I have an error when I call the function (below):

    pre_filter_Computations(radius,theta,cols,rows);

    Is it right or maybe I ll have some problems at run-time?
    SORRY FOR MY ENGLISH
  2. #2
  3. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,223
    Rep Power
    2222
    As you know, this won't work:
    void pre_filter_Computations(double radius[][cols],double theta[][cols],int cols,int rows);
    But it's close.

    I assume that the dimensions of radius[][] and of theta[][] are fixed and will not change. That would mean that every time you call pre_filter_Computations(), those arrays will have the same dimensions. If that is the case, then rows and cols will have be constant values.

    Question: is this in C or in C++? If it is in C, then you would use something like:
    Code:
    #define  ROWS  4
    #define  COLS  4
    
    void pre_filter_Computations(double radius[][COLS],double theta[][COLS]);
    If it is in C++, you could do it the same as in C, or you could declare them as constants:
    Code:
    const int rows = 4;
    const int cols = 4;
    
    void pre_filter_Computations(double radius[][cols],double theta[][cols]);
    However, if you want to support variable numbers of rows and columns, then you would need to do something different.

    Originally Posted by residentelvio
    void pre_filter_Computations(double *radius,double *theta,int cols,int rows);

    double *radius[rows][cols],*theta[rows][cols];

    But now I have an error when I call the function (below):

    pre_filter_Computations(radius,theta,cols,rows);
    That code is very confused.

    With
    void pre_filter_Computations(double *radius,double *theta,int cols,int rows);
    you are declaring radius and theta to be one-dimensional arrays, not two-dimensional.

    With
    double *radius[rows][cols],*theta[rows][cols];
    you are declaring radius and theta to be two-dimensional arrays of pointers to double, effectively making them three-dimensional.

    With
    pre_filter_Computations(radius,theta,cols,rows);
    you are trying to pass tw-dimensional arrays of pointers to a function that expects one-dimensional arrays to non-pointers. C will not allow that.

    Also, you say that you get errors, but you don't tell us what they are. Error and warning messages contain valuable information which we can understand even if you have not yet learned to understand it. You need to share that kind of information with us. Copy-and-pasting them into your message would be preferable.
  4. #3
  5. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    May 2013
    Posts
    57
    Rep Power
    0
    HI, you gotta reason.
    The problem is rows and cols are dimension of a picture! And they are different for ever picture I load with my program. So I have to use pointers.

    The only error I see is when I use the function in the main:
    pre_filter_Computations(radius,theta,rows,cols);

    the error is:

    cannot convert 'double*(*)[(((sizetype)(((ssizetype)cols+-1))+1)]'to'double*' for argument '1' to 'void pre_filter_Computations(double*,double*,int,int)'
  6. #4
  7. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    May 2013
    Posts
    57
    Rep Power
    0
    If I use something like

    double radius[cols*rows]?

    I suppose I have the same as:

    double radius[rows][cols]
  8. #5
  9. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,223
    Rep Power
    2222
    Unfortunately, I have very little time before I leave work and I won't be home for another 5 hours. What I need to explain won't be easy and your limited ability with English will not help us. Also, I have never tried to do this before.

    What you need to do is to change the function parameters to:
    void pre_filter_Computations(double **radius,double **theta,int cols,int rows);
    The double** indicates a two-dimensional array.

    Inside the function you need to interpret the double** as a 2-D array. When I played with that over a year ago, it didn't work. I think you will need to use pointer arithmetic to make it work. For example with a one-dimensional array, to access arr[2], you could write that as *(arr+2). I hope you understand pointers and pointer arithmetic, because you will need to.

    Let us use the example:
    double radius[ROWS][COLS];

    Now, a 2-D array is an array of arrays. Each row is a 1-D array of type double which is COLS long, so each row contains COLS doubles. The second index, col, indexes to the element in the row. There is another 1-D array which is ROWS long, but it is of type double*, meaning that each element is a pointer to an array of double. The first index, row, indexes to the pointer to the row you want to access.

    Here is my initial guess:
    radius[2][3] would be *(radius[2] + 3)
    Meaning we get the pointer to row 2, which is radius[2] and which is a double*, and we add three to it and dereference that address.
    Maybe a better way to write that might be *(*(radius+2) + 3)

    I must leave now. I hope that that gives you some ideas of what to do. And hopefully others here will be able to explain it better or offer a better idea.

    Good luck. I'll check in briefly in 5 hours.

    PS
    How are you creating the array that you want to pass to the function? That is very important.
    Last edited by dwise1_aol; May 15th, 2013 at 07:51 PM.
  10. #6
  11. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    May 2013
    Posts
    57
    Rep Power
    0
    I changed the function as you said but I have the same problem in the main.

    Thanks to help me
  12. #7
  13. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,223
    Rep Power
    2222
    Originally Posted by residentelvio
    I changed the function as you said but I have the same problem in the main.
    I don't know what that means. I have absolutely no idea what your main function looks like. Show us the code. Use code tags.

    I also repeat my questions:
    1. Are you using C or C++?

    2. Additional question: if you are using C, is it C89 or C99? If you don't know the answer, then tell us what compiler you're using. I am using C89, as most C programmers do. It's possible that C99 has some trick features that might help, but if you can't use C99 then that is not an option.

    3. How are you creating your array? This is a very important question.


    I played with the problem a bit and here's what I have:

    This test creates an array in the normal manner and passes it in the normal manner.
    Code:
    #include <stdlib.h>
    #include <stdio.h>
    
    void report(int arry[][3], int rows, int cols);
    
    int main()
    {
        int arr[3][3];
        int  i, j;
        
        for (i=0; i<3; i++)
        {
            for (j=0; j<3; j++)
                arr[i][j] = 10*i + j;
        }
               
        report(arr, 3, 3);
        
        return 0;
    }
    
    void report(int arry[][3], int rows, int cols)
    {
        int i, j;
        
        for (i=0; i<rows; i++)
        {
            for (j=0; j<cols; j++)
                printf("%3d", arry[i][j]);
            printf("\n");            
        }
    }
    That works:
    Code:
    C:TEST>a
      0  1  2
     10 11 12
     20 21 22
    
    C:TEST>
    But this case requires you have a fixed-size array.

    This case creates an array dynamically and passes it as an int**:
    Code:
    #include <stdlib.h>
    #include <stdio.h>
    
    void report(int **arry, int rows, int cols);
    
    int main()
    {
        int **arr;
        int  i, j;
        
        arr = malloc(sizeof(int*)*3);
        
        for (i=0; i<3; i++)
        {
            arr[i] = malloc(sizeof(int)*3);
            for (j=0; j<3; j++)
                arr[i][j] = 10*i + j;
        }
               
        report(arr, 3, 3);
        
        return 0;
    }
    
    void report(int **arry, int rows, int cols)
    {
        int i, j;
        
        for (i=0; i<rows; i++)
        {
            for (j=0; j<cols; j++)
                printf("%3d", arry[i][j]);
            printf("\n");            
        }
    }
    It also works just fine, just like the first one did. For what it's worth, I also tried it with the pointer arithmetic that I had shown you:
    Code:
    void report(int **arry, int rows, int cols)
    {
        int i, j;
        
        for (i=0; i<rows; i++)
        {
            for (j=0; j<cols; j++)
                printf("%3d", *(*(arry+i) + j));
            printf("\n");            
        }
    }
    And that works fine just like the others.

    However, when I try to pass a regular array as an int** it won't compile cleanly:
    Code:
    #include <stdlib.h>
    #include <stdio.h>
    
    void report(int **arry, int rows, int cols);
    
    int main()
    {
        int arr[3][3];
        int  i, j;
        
        for (i=0; i<3; i++)
        {
            for (j=0; j<3; j++)
                arr[i][j] = 10*i + j;
        }
               
        report(arr, 3, 3);
        
        return 0;
    }
    
    void report(int **arry, int rows, int cols)
    {
        int i, j;
        
        for (i=0; i<rows; i++)
        {
            for (j=0; j<cols; j++)
                printf("%3d", *(*(arry+i) + j));
            printf("\n");            
        }
    }
    I got this output:
    C:TEST>gcc -Wall double.c
    double.c: In function `main':
    double.c:23: warning: passing arg 1 of `report' from incompatible pointer type

    C:TEST>
    When I went against my own advice and tried running it, the program crashed. If I cast the array in the function call -- ie,
    report((double**)arr, 3, 3);
    -- then it compiles without warnings, but when I try to run it it still crashes.

    This is why I keep asking you how you are creating that array!

    Hopefully, other forum members have worked with and solved a similar type of problem.

    I'm late for bed now.
  14. #8
  15. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    May 2013
    Posts
    57
    Rep Power
    0
    Hi thanks for helping me, I' m using C++ because I m doing a thesis project and I m working with pictures, using OpenCV libraries. I m using Ubuntu and Eclipse. I can post all the code, but some parts don t work for now, I m just trying to solve a problem a time.

    So I have to create the radius in a separate function and I have to use it in the main too, so It s a pointer call(I don t know the name in english, maybe jump to subroutine)

    I have in the main:

    void pre_filter_Compilations(double **radius,double **theta, int cols, int rows);

    int **radius,**theta;

    Now I have no problems in the main as you said.


    void pre_filter_Computations(double **radius,double **theta,int cols,int rows){

    int a,b;
    double x[cols],y[rows];
    double X[cols][rows], Y[rows][cols];
    double epsilon=0.0001;


    a=cols;
    b=rows;

    for(int j=0;j<a;j++){
    for(int i=-(cols/2);i=((cols/2)-1);i++){
    x[j]= i/(cols/2);
    }
    }
    for(int k=0;k<b;k++){
    for(int z=-(rows/2);z=((rows/2)-1);z++){
    y[k]= z/(rows/2);
    }
    }

    for(int i=0;i<a;a++){
    for(int z=0;z<b;z++){
    X[i][z]=x[i];
    Y[i][z]=y[z];
    }
    }

    for(int a=0;a<rows;a++){
    for(int b=0;b<cols;b++){

    radius=malloc(sizeof(double)*rows);
    radius = sqrt((X[a][b]*X[a][b])+(Y[a][b]*Y[a][b]));

    //radius[(int)rows/2+1][(int)cols/2+1]=1;
    // radius [a][b]= radius[a][b] + epsilon;
    // theta[a][b] = atan2(Y[a][b],X[a][b])*180/PI;
    }
    }
    }

    When I arrived to allocate radius I have an error:

    invalid conversion from 'void*' to 'double**'[-fPERMISSIVE ]

    When I use sqrt:

    invalid argument of unary '*' (have 'double')

    The lastest three lines are commented because I have to change it, because I was using radius and theta as bidimensional array before, and I have to change it!
  16. #9
  17. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    May 2013
    Posts
    57
    Rep Power
    0
    I modified the function. Now I have just a problem when I use malloc function,I mean:

    **theta[z]=(double*)malloc(sizeof(double*)*cols);

    cos I have an error:

    cannot convert'double**'to 'double' in assignment

    but If I use

    theta[z]=(double*)malloc(sizeof(double*)*cols);

    I dont have this error message. Is it right if I use in this mode(the second)?

    Code:
    
    
    void pre_filter_Computations(double **radius,double **theta,int cols,int rows){
    
      int a,b;
      double x[cols],y[rows];
      double X[cols][rows], Y[rows][cols];
      double epsilon=0.0001;
    
    
      a=cols;
      b=rows;
    
      for(int j=0;j<a;j++){
        for(int i=-(cols/2);i=((cols/2)-1);i++){
          x[j]= i/(cols/2);
        }
      }
      for(int k=0;k<b;k++){
          for(int z=-(rows/2);z=((rows/2)-1);z++){
                y[k]= z/(rows/2);
          }
      }
    
      for(int i=0;i<a;a++){
          for(int z=0;z<b;z++){
              X[i][z]=x[i];
              Y[i][z]=y[z];
          }
      }
    
         **radius=(double**)malloc(sizeof(double*)*rows);
           for(int k=0;k<cols;k++){
               radius[k]=(double*)malloc(sizeof(double*)*cols);
          }
         
           **theta=(double**)malloc(sizeof(double*)*rows);
                for(int z=0;z<cols;z++){
                  **theta[z]=(double*)malloc(sizeof(double*)*cols);
                }
    
             for(int a=0;a<rows;a++){
                  for(int b=0;b<cols;b++){
                   
                        radius[a][b] = sqrt((X[a][b]*X[a][b])+(Y[a][b]*Y[a][b]));
                        radius[(int)rows/2+1][(int)cols/2+1]=1;
                        radius [a][b]= radius[a][b] + epsilon;
                        theta[a][b] = atan2(Y[a][b],X[a][b])*180/PI;
    
          }
      }
    }
  18. #10
  19. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,223
    Rep Power
    2222
    Use code tags! Unformatted code is unreadable! Especially when you hide open braces.

    How are you creating those arrays? My examples show that that question is extremely important in determining how to pass the array!

    This makes absolutely no sense at all:
    Code:
    radius=malloc(sizeof(double)*rows);
    radius = sqrt((X[a][b]*X[a][b])+(Y[a][b]*Y[a][b]));
    You are passing radius in to the function, so why throw that away my assigning some other address to it? But then you throw that address away too by assigning a double to it! What are you thinking? What do you think that you're trying to do there? Plus when you throw away what radius was already pointing at (twice!), you neglect to free up that memory. That's a memory leak which is a very serious bug!

    And since you are using C++, why are you using malloc? C++ uses new and delete.
  20. #11
  21. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    May 2013
    Posts
    57
    Rep Power
    0
    So this one is the correct way?

    in the main:

    double **radius,**theta;


    Code:
    void pre_filter_Computations(double **radius,double **theta,int cols,int rows){
    
      int a,b;
      double x[cols],y[rows];
      double X[cols][rows], Y[rows][cols];
      double epsilon=0.0001;
    
    
      a=cols;
      b=rows;
    
      for(int j=0;j<a;j++){
        for(int i=-(cols/2);i=((cols/2)-1);i++){
    	  x[j]= i/(cols/2);
        }
      }
      for(int k=0;k<b;k++){
    	  for(int z=-(rows/2);z=((rows/2)-1);z++){
    	  	  y[k]= z/(rows/2);
    	  }
      }
    
      for(int i=0;i<a;a++){
    	  for(int z=0;z<b;z++){
    		  X[i][z]=x[i];
    		  Y[i][z]=y[z];
    	  }
      }
    
          for(int a=0;a<rows;a++){
          	  for(int b=0;b<cols;b++){
    
                   radius[a][b] = sqrt((X[a][b]*X[a][b])+(Y[a][b]*Y[a][b]));
              }
          }
          radius[(int)rows/2+1][(int)cols/2+1]=1;
    
          for(int a=0;a<rows;a++){
               for(int b=0;b<cols;b++){
                   radius [a][b]= radius[a][b] + epsilon;
                   theta[a][b] = atan2(Y[a][b],X[a][b])*180/PI;
               }
    
    	  }
    }
  22. #12
  23. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,223
    Rep Power
    2222
    I guess. What does the compiler say?
  24. #13
  25. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    May 2013
    Posts
    57
    Rep Power
    0
    Now I m trying to compile just this function. I have an error with library:

    cannot find -lopencv_objdect
    make: ***[prefilter]Error 1

    but I inserted this library in menu:

    Project->Properties->Settings->GCC C++ Linker

    I setted the search path too and the Include paths fot the compiler too...
    If it was not setted yet the file in the #inlcude it has to give me an error, so I don t know I see this errors.
    So I cannot compile

IMN logo majestic logo threadwatch logo seochat tools logo