passing multidimensional arrays to function when the dimension size is not clear

前端 未结 2 1132
眼角桃花
眼角桃花 2021-01-28 00:09

I have a function in my class which should get a multi-dimensional array. the problem is that the value of these dimensions is calculated in the class, using another function an

相关标签:
2条回答
  • 2021-01-28 01:02
    double calcSS(double tfpairexp[][max_ctrl_no][max_rep_no])
    

    One solution is to change the function signature to,

    double calcSS(double ***tfpairexp, int M, int N, int P);
    

    where M, N and P are dimensions of the arrray!

    Or you can pass the instance of your class itself. After all, you've made the dimensions public in your class. And if this function is a member function of the class, then you don't even need to pass anything; you can access them from the function itself like this:

    double calcSS(double ***tfpairexp)
    {
    
          for(int i = 0 ; i < cchips ; i++ )
          {
               for(int j = 0 ; j < max_ctrl_no ; j++ )
              {
                    for(int k = 0 ; k < max_rep_no ; k++ )
                    {
                           //access elements as tfpairexp[i][j][k]
                    }
              }
          }
    
    }
    

    You can see this answer if it solves your problem: using a function template

    0 讨论(0)
  • 2021-01-28 01:07

    The kind of arrays in you are using here (C-style) are not really designed to be used with dynamic sizes, though you can use new to allocate them that way. One solution for function calling is do use a double *** and three size_t parameters for dimensions to pass into a function, but that still requires you to declare the array in the caller with dimensions as large as you will ever need. or you will corrupt your process memory and likely crash.

    A better solution is to use vector which is designed from the beginning to deal with array with runtime-determined sizes. You can either declare a multi-D vector and use it directly, or go for a single-dimensional vector and do a bit of math at access time to convert a triple of coordinates into an index into the vector.

    Either way, you need the vector header, here is how I recommend placing that setup:

    #include <vector> // in your includes
    
    using std::vector; // at global scope immediately after all #includes
    

    Some code samples. I'll use cchips for the size of the third dimension based on another answer. The multidimensional solution looks something like this:

    // at global scope
    typedef vector< vector<double> > vec2double;
    typedef vector< vector<vec2double> > vec3double;
    
    // in the caller of your calcSS after you know how big to make the array {
        vec3double tfairexp(cchips, vec2double(max_ctrl_no, vector<double>(max_rep_no)));
        // now fill up tfairexp
        calcSS(tfairexp);
    // }
    
    // important: pass a reference here, or you will copy the whole array at call time!
    void calcSS(vec3double &tfairexp) {
        // you can use cchips etc here but don't have to:
        for (size_t i = 0; i < tfairexp.size(); i++) {
            for (size_t j = 0; j < tfairexp[0].size(); j++) {
                for (size_t k = 0; k < tfairexp[0][0].size(); k++) {
                    // access tfairexp[i][j][k] here
                }
            }
        }
    }
    

    That solution will actually do 1+j+j*k allocations of dynamic arrays. You could instead write a wrapper class that would "own" the vector and do the dimension-translation stuff, and have the class you're currently writing use that. I'm making some stylistic sacrifices to continue to use your "public class member variables for dimension sizes" approach. However, this one more closely models how the compiler translates C-style multidimensional arrays, and only does one memory allocation per run:

    // as a member of your class -- returns a live reference that can be assigned to!
    double &vec3_get(vector<double> &array, const size_t i, const size_t j, const size_t k) {
        return array[i*max_ctrl_no*max_rep_no + j*max_rep_no +k];
    }
    
    // in caller of calcSS {
        vector<double> tfairexp(cchips*max_ctrl_no*max_rep_no);
        // fill in by doing vec3_get(tfairexp, i, j, k) = val;
        calcSS(tfairexp)
    // }
    
    // again, pass a reference to the vector!
    void calcSS(vector<double> &tfairexp) {
        for (size_t i = 0; i < cchips; i++) {
            for (size_t j = 0; j < max_ctrl_no; j++) {
                for (size_t k = 0; k < max_rep_no; k++) {
                    // access vec3_get(tfairexp, i, j, k) here
                }
            }
        }
    }
    
    0 讨论(0)
提交回复
热议问题