You can either pass the array considering as a sparse array i.e. by doing void someFunc(int** myArray) or you can pass it as a normal array by leaving off at the max the first dimension i.e. void someFunc(int myArray[COLS]) . Also read this.
Consider constructing your 2D array using vectors since it is more flexible that way.
Why do you want to return a 2D array which is a member of the class when all you are doing in the 'population()' method is make changes to the same array? You can just call the 'population()' function in your constructor and your 2D array would have the updated/required values.
Your class design looks weird, but I will leave that up to you to figure out.
testCase::testCase(int i, int *matrix2, float mFit)
I see no reason to be using the scope operator in the above snippet
since the definition you are coding is occuring within the
Using the this pointer is unnecessary in the above snippet.
In the following line:
the indexes cellId and freq are out of bounds and hopefully cause
your program to crash. In addition, naming specific indexes in this
context refers to a specific element of matrix, not to matrix itself.
It is incorrect syntax to use an empty  operator in the context of
assignment as in the above line in reference to matrix2.
In C/C++ you can't assign one array to another. I also prefer not to try to assign a pointer to an array to another pointer to an array.
To assign the values of an array passed to this constructor I would
use loops to assign each element separately from one array to the
In summary, I'd try this:
testCase(int i, int matrix2[cellId][freq], float mFit)
for(int j = 0; j < cellId; ++j)
for(int k = 0; k < freq; ++k)
matrix[j][k] = matrix2[j][k];