Pass Object by Reference error in C++ - c++

I have a MatrixTypeheader file which has the following definition :
http://pastebin.com/DMzf1wGB
//Add Two Matrices and store result into another matrix
void Add(MatrixType otherMatrix, MatrixType& resultMatrix);
The implementation of the method above is as such :
void MatrixType::Add(MatrixType otherMatrix, MatrixType& resultMatrix)
{
cout << "Inside Add func!" << endl;
cout << "other matrix : " << endl;
otherMatrix.PrintMatrix();
for (int i = 0; i < numRows; i++) {
for (int j = 0; j < numCols; j++) {
resultMatrix.values[i][j] = values[i][j] + otherMatrix.values[i][j];
}
cout << "\n";
resultMatrix.PrintMatrix();
cout << "\n";
}
}
Definition of PrintMatrix() :
void MatrixType::PrintMatrix()
{
//Pre: None
//Post: Matrix is printed row wise
for (int i = 0; i < numRows; i++) {
cout << "[ ";
for (int j = 0; j < numCols; j++) {
cout << values[i][j];
}
cout << "]";
cout << "\n";
}
}
Now in my Main.cpp I have MatrixType array like this : MatrixType matrixStore[10] to store 10 MatrixType objects. The complete code for Main.cpp is here : http://pastebin.com/aj2eEGVS
int rows = matrixStore[index1].getRowSize();
int cols = matrixStore[index1].getColSize();
cout << "The two matrices can be added!" << endl;
cout << "Computing... " << endl;
//Create Result Matrix and a pointer variable to it
MatrixType pResultMatrix = MatrixType(rows, cols);
matrixStore[resultIndex] = pResultMatrix;
//Invoke Add function
matrixStore[index1].Add(matrixStore[index2], matrixStore[resultIndex]);
Now when in my Add() function I do otherMatrix.PrintMatrix() it prints out the values of the matrix invoking the Add() function. And due to this => either I do not have reference to the matrix object invoking the method or the matrix object being passed as the parameter!
Also whenever I do PrintMatrix() after I have added values (in the next round of Switch Case), I always get junk values.
Any solution/explanation to this ?
TIA

The main problem is not in this part of your code but during the matrix creation/initialization. You are storing objects in the array which can be good (especially I like it because it is created on the stack which is much faster, just be aware to do not create too long array to avoid stack overflow) but you have to consider this overall of your code.
For example in the Main.cpp line 38 you copy the content of matrixobject into the array but after that you modify the matrix object which is different from the object which is in the array! This means that the content of the matrix object in the array has some random values. You should modify directly the object in the array, it does not make any sense to have that temporary one.
For example:
matrixStore[index] = MatrixType(rows, cols);
for (int i = 0; i < rows; i++)
{
std::cout << "Row " << i << " : ";
for (int j = 0; j < cols; j++)
{
std::cin >> value;
matrixStore[index].StoreItem(value, i, j);
}
}
I think after this change the part what you copied here should work because there you are working in the array directly.
Some small suggestions:
Pass MatrixType object always as reference if possible. For example, in Add function also the òtherMatrix can be a const ref, your code will be much efficient because the object copy will be not involved. For example:
void MatrixType::Add(const MatrixType& otherMatrix, MatrixType& resultMatrix);
Here the otherMatrix is an input, the resultMatrix is (can be) an output parameter.
In C++ there is real bool type. Avoid bool isAddComp ... if (isAddComp != 0)code, just use if (isAddComp), this is the C++ way.
I would start to use std::vector instead of common arrays, much more flexible and very useful to learn how can you use it.
Personally I would not use ùsing namespace for std it is short and better to read your code (but maybe this is just my code style).

Looking at the code here: http://pastebin.com/aj2eEGVS
It looks like the only reason you're creating a local matrix in all your paths, for example:
MatrixType matrix = MatrixType(rows, cols);
is to assign values to the members numRows and numCols. I see you have a commented out SetSize method. I would assume you don't want to do use it because you think the rows and columns shouldn't change after creation.
In that case, your matrixStore should be created as pointers:
MatrixType* matrixStore[10];
Now instead of doing:
MatrixType matrix = MatrixType(rows, cols);
matrixStore[index] = matrix;
You do this:
matrixStore[index] = new MatrixType(rows, cols);
And just use:
matrixStore[index]->StoreItem(value, i, j);
or whatever you want to do with it.
In the end, you just call:
delete matrixStore[index];
For all matrices you have used "new" on. The best way to do this is to assign them to nullptr in the beginning.
MatrixType* matrixStore[10];
for ( unsigned int i = 0; i < 10; ++i )
{
matrixStore[i] = nullptr;
}
And in the end:
for ( unsigned int i = 0; i < 10; ++i )
{
if (nullptr != matrixStore[i])
{
delete matrixStore[i];
}
}

In short, matrixStore stores object values, not pointers (as you expect).
//Create Result Matrix and a pointer variable to it
MatrixType pResultMatrix = MatrixType(rows, cols);
matrixStore[resultIndex] = pResultMatrix;
Seems you expect to store pointer variable, but it's not true. MatrixType value is stored in matrixStore.
The result of this is incorrect matrixStore filling (code from your link):
MatrixType matrix = MatrixType(rows, cols);
matrixStore[index] = matrix;
cout << "Address of matrixStore[index] : " << &matrixStore[index] << endl;
cout << "Address of new matrix is : " << &matrix << endl;
int value;
for (int i = 0; i < rows; i++) {
cout << "Row " << i << " : ";
for (int j = 0; j < cols; j++) {
cin >> value;
matrix.StoreItem(value, i, j);
}
}
All changes to matrix are lost as matrixStore contains old copy of matrix object.
Solution:
The proper declaration of matrixStore to keep pointers is:
MatrixType* matrixStore[10]
In case you would like to operate with MatrixType value objects you need to copy objects into matrixStore all time you've modified them.

Looking at the code in http://pastebin.com/aj2eEGVS
It seems to me you are not initializing the matrix in matrixStore. You are filling the local variable matrix.
MatrixType matrix = MatrixType(rows, cols); // LOCAL VARIABLE
**matrixStore[index] = matrix;** // you are copying the uninitialized matrix
// ...
int value;
for (int i = 0; i < rows; i++) {
cout << "Row " << i << " : ";
for (int j = 0; j < cols; j++) {
cin >> value;
matrix.StoreItem(value, i, j); // LOCAL VARIABLE
}
}
cout << endl;
//Print matrix so the use can see
matrix.PrintMatrix(); // PRINT LOCAL VARIABLE

Related

Passing 2D Dynamic Array in a Function with parameter from array.h in C++

I've separated my code into 3 files: main.cpp, array.h, array.cpp
My code asks the user to input size of a square 2D matrix and I implement some functions (transpose, addition of 2 2D Arrays, etc)
my array.cpp's constructor initializes a dynamic array of size s and puts all entries to 0s.
Array::Array(int s)
{
// The constructor creates a dynamic array v[s][s], and set size to s.
// initialize all entries v[i][j] to 0.
int **v = new int*[s];
for(int i = 0; i < s; ++i)
v[i] = new int[s];
for(int i = 0; i < s; i++)
for(int j = 0; j < s; j++)
v[i][j] = 0;
}
Array::~Array()
{
// The destructor deletes v.
int arraysize = sizeof(v)/sizeof(v[0]);
for(int i = 0; i < arraysize; ++i)
{
delete [] v[i];
}
delete [] v;
}
This is part of my main.cpp that i'm having trouble with.
I have a function asking the user to input entries for 2d array on the top of my main function, but I've been getting error "type 'Array' does not provide a subscript operator"
#include <iostream>
#include "array.h"
using namespace std;
// input array
void input(Array &C)
{
int i, j;
for(i = 0; C[i][0] == 0; i++)
for(j = 0; C[0][j] == 0; j++)
{
cin >> C[i][j];
}
}
int main(void)
{
//input size
int size;
cout << "Please input array size:" << endl;
cin >> size;
//input A, B
Array A(size), B(size);
cout << "Please input " << size << "x" << size << "integer array A:" << endl;
input(A);
cout << "Please input " << size << "x" << size << "integer array B:" << endl;
input(B);
........
I have to use the parameter (Array &C) for the input function, but I'm not sure how to change the body of the input funtion
First off, the expression sizeof(v)/sizeof(v[0]) does not do what you expect it to do.
This would work for a statically-allocated array, not for a dynamically-allocated array.
A sizeof expression is translated during compilation-time, by applying it on the type of of the operand.
In your case, the operand is v and its type is int**.
Therefore, sizeof(v) is equivalent to sizeof(int**), and sizeof(v[0]) is equivalent to sizeof(int*).
You expect the expression sizeof(v) to give you the size of the dynamically-allocated array pointed by v, but the compiler cannot guess (during compilation-time) what this size is going to be during runtime.
With regards to the actual question at hand (and as already mentioned in a comment to it), you'll need to implement the following functions in your Array class:
Reader - int* Array::operator[](int index) const {return v[index];}
Writer - int*& Array::operator[](int index) {return v[index];}
BTW, declaring in the constructor a local variable named v, will result in the initialization of that local variable instead of in the initialization of the member variable of the same name.

C++: Error while allocating memory for a two dimensional array using functions

I am trying to understand passing by reference and passing by value. In this program I have a two dimensional array which is declared in main and whose size is allocated in a function. In the allocate2DArrayRef() function, I obtain the two sizes and dynamically allocate and initialize the array Array2D.
Now I am trying to understand how to do the same by pointers. I have written another function allocate2DArrayPtr() in where I pass a pointer to the two dimensional array, get the value of the sizes - sizeX and sizeY and then allocate the memory to the variable secArray2D.
When I run the program it hangs when I try to print out secArray2D. I am assuming this implies that the function allocate2DArrayPtr() has not been successful in dynamically allocating memory to the array secArray2D.
My final goal is to write a program which has a function that dynamically allocated memory and initializes multiple arrays of various dimensions which are read from an input file. I know I can expand on passing by reference function allocate2DArrayRef() to achieve my goal. But I am curious to learn why my function allocate2DArrayPtr() is not working as I want to be clear on how to pass by pointers also. I do know how to change allocate2DArrayPtr() to return a pointer but I would like to pass the array as a parameter.
I am running the program on windows 7 using Codeblocks 13.12 IDE.
#include <iostream>
using namespace std;
void allocate2DArrayRef(int **&, int &, int &);
void allocate2DArrayPtr(int ***, int *, int *);
int main()
{
int sizeX, sizeY;
int **Array2D;
allocate2DArrayRef(Array2D, sizeX, sizeY);
for(int i=0; i< sizeX; i++)
{
for(int j=0; j< sizeY; j++)
{
cout << "Array2D[" << i << "][" << j << "]:" << Array2D[i][j] << endl;
}
}
cout << endl << endl;
int **secArray2D;
allocate2DArrayPtr(&secArray2D, &sizeX, &sizeY);
for(int i=0; i<sizeX; i++)
{
for(int j=0; j<sizeY; j++)
{
cout << "secArray2D[" << i << "][" << j << "]:" << secArray2D[i][j] << endl;
}
}
return 0;
}
void allocate2DArrayRef(int **&locArray, int& indexFirst, int& indexSecond)
{
indexFirst = 4;
indexSecond = 5;
locArray = new int*[indexFirst];
for(int i=0; i<indexFirst ; i++)
{
locArray[i] = new int[indexSecond];
for(int j=0; j<indexSecond; j++)
{
locArray[i][j] = i*j;
}
}
}
void allocate2DArrayPtr(int ***locArray, int *indexFirst, int *indexSecond)
{
*indexFirst = 2;
*indexSecond = 3;
int **temp = *locArray;
temp = new int*[*indexFirst];
for(int i=0; i<(*indexFirst) ; i++)
{
temp[i] = new int[*indexSecond];
for(int j=0; j<(*indexSecond); j++)
{
temp[i][j] = i+j;
}
}
}
The reason allocate2DArrayPtr does not work is you never set locArray to point to the array you create in the function. This means when you return from the function secArray2D still is uninitialized.
Adding
*locArray = temp;
To the end of allocate2DArrayPtr will fix the problem.
Or you can reference your to temp like this:
int **&temp = *locArray;

Error in passing a matrix as an argument

I am trying to get an understanding of how to work with matrices in C++. The code at the bottom is supposed to take an input matrix and return the places where there are 0s. However, I am getting the following errors:
matrix.cpp:47:3: error: no matching function for call to 'make_zero' make_zero(i,j,l);
^~~~~~~~~
matrix.cpp:8:6: note: candidate function not viable: no known conversion from 'double [i][j]' to
'double (*)[col]' for 3rd argument
void make_zero(int row, int col, double matrix[row][col])
^
1 error generated.
when I try to run the following code:
// Matrix
#include <iostream>
#include <stdio.h>
using namespace std;
void make_zero(int row, int col, double matrix[row][col])
{
int k,l;
for(k=0;k<row;k++)
for(l=0;l<col;l++)
{
if(matrix[k][l]==0)
printf("%d %d\n",k,l);
}
}
int main ()
{
int i = 0,j = 0;
cout << "Enter no of rows of the matrix";
cin >> i;
cout << "Enter no of columns of the matrix";
cin >> j;
double l[i][j];
int p = 0, q = 0;
while (p < i) {
while (q < j) {
cout << "Enter the" << p + 1 << "*" << q + 1 << "entry";
cin >> l[p][q];
q = q + 1;
}
p = p + 1;
q = 0;
}
cout << l << "\n";
make_zero(i,j,l);
}
Any help would be appreciated. Thanks.
There are a bunch of ways to do this with pointers. The most common is
void make_zero(int row, int col, double ** matrix)
defines a pointer (usually rows) to a pointer (usually columns). Unfortunately
double l[i][j];
does not define a pointer to a pointer. If this syntax is supported by the compiler, and the compiler is not required to allow arrays of variable length, it most likely defines a pointer to a 1D array (double l[i*j];) and hides the indexing arithmetic used to convert the array to two dimensions. Anyway, it can't be passed to a double ** because it isn't a double **
Trying to pass as an array is troublesome
void make_zero(int row, int col, double matrix[][NUMBER_OF_COLUMNS])
The number of columns in the array must be known to perform the indexing arithmetic and be provided to any functions called with it. This means that number of columns cannot be changed at run time because the indexing used by the function will be rendered invalid.
Getting around this would require changes to the compiler that will drive it further and further from the C++ standard. A bad idea since there are a number of simple ways around calling functions with multi dimensional arrays. Most depend on arrays of arrays or std::vectors of std::vectors.
And when it comes to these solutions, as far as I'm concerned, the best is don't. I'm not going to cover them.
None of the arrays representing a dimension are guaranteed to be anywhere close to the others in memory, and this limits the CPU's ability to read and cache. Without caching and being able to look ahead, a modern CPU is at a serious performance disadvantage. (Read for more information: Why is it faster to process a sorted array than an unsorted array?)
So what you want is a 1 D array, and those are easy to pass around. The indexing math is also easy, row number * size of column + column number, but you need to pass at least the size of the column around. Rather than scatter the book-keeping around like this:
void make_zero(int row, int col, std::vector<double> matrix)
make a wrapper class like this:
class Matrix
{
private:
std::vector<double> myArray;
size_t nrRows;
size_t nrColumns;
public:
Matrix(size_t rows, size_t columns) :
myArray(rows * columns), // allocate vector to store matrix.
nrRows(rows),
nrColumns(columns)
{
}
size_t getNrRows() const
{
return nrRows;
}
size_t getNrColumns() const
{
return nrColumns;
}
// gets value at row, column and returns a reference so caller can
// modify the value
double& operator()(size_t row, size_t column)
{
// note: No sanity check for row >= nrRows or column > nrColumns
return myArray[row * nrColumns + column];
}
// gets value at row, column and returns a copy so caller cannot
// change the contents of the Matrix
double operator()(size_t row, size_t column) const
{
return myArray[row * nrColumns + column];
}
};
Using the vector gets around a number of common pointer-to-array problems by managing its own memory. No destructor is required and Matrix can be copied and moved without requiring special handling because vector performs all that heavy lifting for us.
And as a usage example, let's make a function that prints the matrix out:
std::ostream & operator<<(std::ostream & out, const Matrix & in)
{
for (size_t i = 0; i < in.getNrRows(); i++)
{
for (size_t j = 0; j < in.getNrColumns(); j++)
{
out << in(i,j) << ' ';
}
out << "\n";
}
return out;
}
And modifying OP's main function to use Matrix we get:
int main()
{
int i = 0, j = 0;
cout << "Enter no of rows of the matrix";
cin >> i;
cout << "Enter no of columns of the matrix";
cin >> j;
Matrix matrix(i,j);
int p = 0, q = 0;
while (p < i)
{
while (q < j)
{
cout << "Enter the" << p + 1 << "*" << q + 1 << "entry";
cin >> matrix(p,q);
q = q + 1;
}
p = p + 1;
q = 0;
}
cout << matrix << "\n";
make_zero(matrix);
}
void make_zero(int row, int col, double ** matrix)
Note, that you need to pass also size of the matrix separately.
Also you can use
std::vector<std::vector<double> >
instead and pass this object by reference, pointer, or just make a copy.
Actually, it works, but your problem in this line also:
double l[i][j];
i, j is unknown during the compile time.
You have 2 ways.
1) dynamically allocate the memory
2) use std::vector<std::vector<double> >. Default constructor already sets zero values. But you can do it manually like this:
#include <iostream>
#include <vector>
void make_zero(std::vector<std::vector<double> > & to_zero) {
for (int i = 0; i < to_zero.size(); ++i) {
for (int j = 0; j < to_zero[i].size(); ++j) {
to_zero[i][j] = 0;
}
}
}
void print_double_vector(const std::vector<std::vector<double> > & to_print) {
for (int i = 0; i < to_print.size(); ++i) {
for (int j = 0; j < to_print[i].size(); ++j) {
std::cout << to_print[i][j] << " ";
}
std::cout << std::endl;
}
std::cout << std::endl;
}
int main() {
// your code goes here
int n, m;
std::cin >> n >> m;
std::vector<std::vector<double> > d(n, std::vector<double>(m));
print_double_vector(d);
make_zero(d);
print_double_vector(d);
return 0;
}
http://ideone.com/0X53Yj

C++ Scope Resolution Issue

Yesterday my class had a laboratory exam where-in we had to make a matrix class and overload the operation+(). I thought that I had it correct until I went to go do my unit testing... I know this is a lot of text; however, I spent the remainder of the lab trying to figure out what was going wrong and could NOT figure out why the Temporary Object Matrix was going out of scope prior to the assignment operator call.
Code as follows:
Matrix Header
#include <iostream>
#include <iomanip>
using namespace std;
class Matrix
{
Public:
// Constructor and Destructor Suite
Matrix(int x, int y); // Lab TA stated that Matricies would never go above two dimensions
~Matrix();
// Access and Mutation
void set(int row, int column, int value); // This function sets the value of a given matrix coordinate at row, column to value
int get(int row, int column) const; // This function returns the value of a matrix at row, column
Matrix& operator=(const Matrix& Q)
{
cout << "Called Assignment" << endl;
int r, c;
r = Q.rows; c = Q.columns;
for (int i = 0; i < r; i++)
{
for (int k = 0; k < c; k++)
{
cout << "Address of Calling Objet pointer Int: " << this->pMatrixOfInt[i][k] << setw(5) << *this->pMatrixOfInt[i][k] << endl;
cout << "Address of Reference Object: " << Q.pMatrixOfInt[i][k] << setw(5) << *Q.pMatrixOfInt[i][k] << endl;
*(this->pMatrixOfInt[i][k]) = *(Q.pMatrixOfInt[i][k]);
}
}
return *this;
}
const Matrix operator+(const Matrix& Q);
friend ostream& operator<<(ostream& output, const Matrix& Q);
friend istream& operator>>(istream& input, Matrix& Q);
private:
int rows, columns;
int* pMatrixOfInt[50][50]; // Specification document said that these values would never go above 50
};
Matrix.cpp
/*
Matrix Class Definition
14 March 2014
*/
#include <iomanip>
#include <iostream>
#include "Matrix.h"
// Constructor
Matrix::Matrix(int x, int y)
{
cout << "Constructor Called" << endl;
this->rows=x;
this->columns=y;
for (int i=rows-1; i>=0; i--) // If X and Y are both 50 then the starting value
{ // for i and k should be 49 because of how arrays
for (int k=columns-1; k>=0; k--) // are indexed. Hence the rows-1
{
pMatrixOfInt[i][k] = new int;
}
}
}
// Destructor
Matrix::~Matrix()
{
cout << "Destructor Called" << endl;
for (int i=rows-1; i>=0; i--) // If X and Y are both 50 then the starting value
{ // for i and k should be 49 because of how arrays
for (int k=columns-1; k>=0; k--) // are indexed. Hence the rows-1
{
delete pMatrixOfInt[i][k];
}
}
}
// Access and Mutation
void Matrix::set(int row, int column, int value)
{
*pMatrixOfInt[row][column] = value;
}
int Matrix::get(int row, int column) const
{
return *pMatrixOfInt[row][column];
}
// Overloaded Addition Operator (Possible Scope Problem)
const Matrix Matrix::operator+(const Matrix& Q)
{
cout << "Addition Operator Called" << endl;
int rows, columns;
rows = Q.rows;
columns = Q.columns;
Matrix newMatrix(rows, columns);
cout << "newMatrix Rows: " << newMatrix.rows << " -- newMatrix columns: " << newMatrix.columns << endl; // Make a new matrix. Constructor will initialize the pointer Matrix
int newValue;
for (int i=0; i<rows; i++)
{
for (int k=0; k<columns; k++)
{
newValue = this->get(i,k);
newValue += Q.get(i,k);
newMatrix.set(i,k, newValue);
cout << setw(5) << newMatrix.get(i, k);
}
cout << "\n";
}
return newMatrix;
}
// Friend definitions for i/ostreams.
ostream&::operator<<(ostream& output, const Matrix& Q)
{
for (int r = 0; r<Q.rows; r++)
{
for (int c = 0; c<Q.columns; c++) // hahaha
{
output << setw(4) << Q.get(r,c);
}
output << "\n";
}
return output;
}
istream&::operator>>(istream& input, Matrix& Q)
{
int value;
for (int r = 0; r<Q.rows; r++)
{
for (int c = 0; c<Q.columns; c++)
{
input >> value;
Q.set(r,c,value);
}
}
return input;
}
When I tried to do something like this:
newMatrix = oldMatrixA + oldMatrixB;
cout << newMatrix;
I received the following series of outputs and then a BLOCK_HEADER_ERROR:
Addition Operator Called
0 1 2 3
1 3 5 7
Destructor Called
Assignment Called
Lots of output here regarding address of calling object and value along with the reference object and value of that too
!!!BLOCK_HEADER_ERROR!!!
Can anyone tell me why the Temporary Object returned by the addition operator is going out of scope prior to the assignment operator even though they are on the same line and newMatrix is a return object and thus should not be destroyed until the scope calling it calls for its destruction?
Thank you in advance for your help, I didn't sleep well last night because the TA made me turn in work that I knew was bugged and I haven't been able to figure out the problem.
I know that it's a lot of code and this is the longest question I've posted to StackOverflow ever; however, I like sleeping well and I don't think I'll rest soundly until I know what's going wrong.
Why do you use pointers to store the values? Use plain integers instead and you are fine.
At first think about the "too early" destruction:
In your code you actually have two temporaries (if no return value optimization takes place):
The first one is newValue and the second one your rvalue temporary that gets returned by operator+.
After a copy of newValue to the temporary rvalue has been made newValue is destructed (the message you see).
Second problem is: You did not specify a custom copy constructor (think about the rule of three). Hence the rvalue temporary copy has all the pointers to the integers that you freed when destructing newValue.
If you can't use plain integers, then you have to write your own copy constructor that really copies (allocates new integers for the new matrix).
If you can use plain integers, then use them and everything is fine (no need for custom destructor/copy constructor/copy assignment operator)
An example copy constructor:
Matrix::Matrix(const Matrix &other) {
this->rows=other.rows;
this->columns=other.columns;
for (int row = 0; row < rows; ++row) {
for (int column = 0; column < columns; ++column) {
// allocate a new integer with the value
// copied from the other matrix
pMatrixOfInt[row][column] = new int(*other.pMatrixOfInt[row][column]);
}
}
}

c++ error: invalid types 'int[int]' for array subscript

Trying to learn C++ and working through a simple exercise on arrays.
Basically, I've created a multidimensional array and I want to create a function that prints out the values.
The commented for-loop within Main() works fine, but when I try to turn that for-loop into a function, it doesn't work and for the life of me, I cannot see why.
#include <iostream>
using namespace std;
void printArray(int theArray[], int numberOfRows, int numberOfColumns);
int main()
{
int sally[2][3] = {{2,3,4},{8,9,10}};
printArray(sally,2,3);
// for(int rows = 0; rows < 2; rows++){
// for(int columns = 0; columns < 3; columns++){
// cout << sally[rows][columns] << " ";
// }
// cout << endl;
// }
}
void printArray(int theArray[], int numberOfRows, int numberOfColumns){
for(int x = 0; x < numberOfRows; x++){
for(int y = 0; y < numberOfColumns; y++){
cout << theArray[x][y] << " ";
}
cout << endl;
}
}
C++ inherits its syntax from C, and tries hard to maintain backward compatibility where the syntax matches. So passing arrays works just like C: the length information is lost.
However, C++ does provide a way to automatically pass the length information, using a reference (no backward compatibility concerns, C has no references):
template<int numberOfRows, int numberOfColumns>
void printArray(int (&theArray)[numberOfRows][numberOfColumns])
{
for(int x = 0; x < numberOfRows; x++){
for(int y = 0; y < numberOfColumns; y++){
cout << theArray[x][y] << " ";
}
cout << endl;
}
}
Demonstration: http://ideone.com/MrYKz
Here's a variation that avoids the complicated array reference syntax: http://ideone.com/GVkxk
If the size is dynamic, you can't use either template version. You just need to know that C and C++ store array content in row-major order.
Code which works with variable size: http://ideone.com/kjHiR
Since theArray is multidimensional, you should specify the bounds of all its dimensions in the function prototype (except the first one):
void printArray(int theArray[][3], int numberOfRows, int numberOfColumns);
I'm aware of the date of this post, but just for completeness and perhaps for future reference, the following is another solution. Although C++ offers many standard-library facilities (see std::vector or std::array) that makes programmer life easier in cases like this compared to the built-in array intrinsic low-level concepts, if you need anyway to call your printArray like so:
printArray(sally, 2, 3);
you may redefine the function this way:
void printArray(int* theArray, int numberOfRows, int numberOfColumns){
for(int x = 0; x < numberOfRows; x++){
for(int y = 0; y < numberOfColumns; y++){
cout << theArray[x * numberOfColumns + y] << " ";
}
cout << endl;
}
}
In particular, note the first argument and the subscript operation:
the function takes a pointer, so you pass the name of the multidimensional array which also is the address to its first element.
within the subscript operation (theArray[x * numberOfColumns + y]) we access the sequential element thinking about the multidimensional array as an unique row array.
If you pass array as argument you must specify the size of dimensions except for the first dim. Compiler needs those to calculate the offset of each element in the array. Say you may let printArray like
void printArray(int theArray[][3], int numberOfRows, int numberOfColumns){
for(int x = 0; x < numberOfRows; x++){
for(int y = 0; y < numberOfColumns; y++){
cout << theArray[x][y] << " ";
}
cout << endl;
}
}