Dynamic Array w/ <vector>: In/Out of Function

Up to now, I have been creating dynamic arrays the old-fashioned way: using new and delete and manually taking care of memory/pointer house-keeping.

I would now like to get comfortable with the new way of handling dynamic arrays: using <vector>.

I have written a small program that passes a 2D array into a sub-routine, performs some manipulations on the array elements, and then returns the array to the main program. Here is a drastically abridged version of the program:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <vector>

. . .

void function_M(vector<vector<double> > input_2D_Array) {
// perform some operations on the elements of the 2D matrix
// for example, multiply all elements by 2
. . .

return;
}

. . .

int main()

   vector<vector<double> > Matrix_A;  // Create 2D matrix
   int M, N; // The number of rows and columns of matrix
   int i;  // array index 

. . .

 // prompt user to enter matrix dimensions, M and N. Then re-size the matrix to
 // the specified dimensions: M X N

. . .

   Matrix_A.resize(M);
   for (i = 0; i < M; i++) Matrix_A[i].resize(N);

. . .

 // Pass Matrix_A into the sub-routine to perform the necessary operations

   function_M(Matrix_A);

 // Output Matrix_A to check results

. . .

   return 0;
}


When I step through the program, the array is properly changed within the sub-routine. However, the changes don't seem to be passed out to the main program. I had assumed arrays were always passed by reference, so any changes made within the sub-routine on an array variable were changed in the main program too. Was I mistaken? If so, how do I correct it?

(Any other advice for making this a better program would be welcome too.)
I think you need to put an & and send the adress of the vector through. I am also very new to this vector thing as well though ...

1
2
3
4
5
6
7
8
9
10
11
12
13

#include <vector>

. . .

void function_M(vector<vector<double> > & input_2D_Array) {
// perform some operations on the elements of the 2D matrix
// for example, multiply all elements by 2
. . .

return;
}


Last edited on
dhilchie is right.
You are passing your array by copy to the function. You need to pass it by reference.

By the way, vectors of vectors are not a very efficient way of implementing 2D arrays.
Thanks for the suggestion. That works! I didn't change anything else.

However, I am a little puzzled about why it works.
If the type of parameter accepted by the sub-routine changes, shouldn't the type of parameter fed into the sub-routine also have to change (which I did not do)?

Perhaps I am confusing it with the old C way of defining sub-routines with pointers (e.g. - int* intFlag) and also feeding in the address of the variable instead of the variable itself when calling the sub-routine (e.g. - &intFlag).

In this case, I added the ampersand (&) to the parameter list in the sub-routine definition, but I still fed in the variable itself when calling the sub-routine. Is this correct?

"toum": Anytime I look for information about dynamic arrays, <vectors> are the recommended approach. However, you say this approach is inefficient. What approach would you recommend for dynamic arrays of 2 dimensions (or higher)?
If the type of parameter accepted by the sub-routine changes, shouldn't the type of parameter fed into the sub-routine also have to change (which I did not do)?

The compiler is allowed to perform some type conversion automatically. For example you never get a compile error when you pass an int variable to a function that expects an unsigned int. The conversion of any type to its reference is one of these allowed automatic conversions.


"toum": Anytime I look for information about dynamic arrays, <vectors> are the recommended approach. However, you say this approach is inefficient. What approach would you recommend for dynamic arrays of 2 dimensions (or higher)?

I did not say vectors are not efficient, but that vectors of vectors are not.
It's the equivalent of doing that:
1
2
3
4
5
6
7
int r;
double** Matrix;
Matrix = (double**) malloc( NumberOfRows * sizeof(double*) );
for( r = 0; r < NumberOfRows; r++ )
{
    Matrix[r] = (double*) malloc( NumberOfColumns * sizeof(double) );
}

I clearly prefer defining my own class:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include <vector>
class Matrix {
private:
    unsigned int RowCount, ColumnCount;
    std::vector<double> data;
    
public:
    Matrix( unsigned int RowNb = 0, unsigned int ColumnNb = 0 ): RowCount(RowNb), ColumnCount(ColumnNb)
    {
        data.resize(RowCount*ColumnCount);
    }
    Matrix( const Matrix& other )
    {
        RowCount = other.RowCount;
        ColumnCount = other.ColumnCount;
        data = other.data;
    }
    Matrix& operator= (const Matrix& other)
    {
        RowCount = other.RowCount;
        ColumnCount = other.ColumnCount;
        data = other.data;
        return *this;
    }
    ~Matrix()
    {;}

    double operator() (unsigned int r, unsigned int c) const
    {
        return data[r*ColumnCount + c];
    }
    double& operator() (unsigned int r, unsigned int c)
    {
        return data[r*ColumnCount + c];
    }
};
Topic archived. No new replies allowed.