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

Jun 6, 2013 at 5:29pm
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.)
Jun 6, 2013 at 5:40pm
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 Jun 6, 2013 at 5:41pm
Jun 6, 2013 at 8:33pm
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.
Jun 7, 2013 at 3:38am
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)?
Jun 7, 2013 at 6:39pm
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.