I am currently implementing a class that can represent matrices using dynamic arrays with double pointers (of type double), overloaded */-/+ operators
for matrix arithmetic & overloaded stream insertion operator for outputting the matrices.
My project requires that the user inputs a sequence of inputs separated by spaces into a string, with the number of terms in the string equating the number of columns, and the number of string inputs equating rows. I've been able to successfully write out my class function definitions, but when I compile and run my code, once the program reaches the overloaded insertion operator call, it only prints one memory address rather than each value in the array regardless of how many rows or columns I try.
My class definition:
class clMatrix {
private:
int rows, cols ;
double **arr ;
public:
clMatrix() ;
~clMatrix() ;
void userInput(char matrixId, int &rowN, int &colN) ;
friend ostream &operator<<(ostream& os, const clMatrix*&) ;
friend clMatrix &operator+(const clMatrix&, const clMatrix&) ;
friend clMatrix &operator-(const clMatrix&, const clMatrix&) ;
friend clMatrix &operator*(const clMatrix&, const clMatrix&) ;
} ;
My class function definitions(specifically input and output, as the arithmetic operators I haven't even tested since I lack output to test) and main:
Output function:
ostream& operator<<(ostream& os, const clMatrix *&printMatrix) {
for(int i = 0; i < printMatrix->rows; ++i) {
os << "\nRow " << i+1 << ": " ;
for(int j = 0; j < printMatrix->cols; ++j) {
os << printMatrix->arr[i][j] << " " ;
}
}
os << endl ;
return os ;
}
Input function:
void clMatrix::userInput(char matrixId, int &rowN, int &colN) {
string in ;
int idx, rowLen, colLen ;
double rowarr[50] ;
bool firstRow = 1 ;
colLen = 0 ;
rowLen = 0 ;
idx = 0 ;
cout << "Matrix: " << "'" << matrixId << "'" << endl ;
cout << "Enter row 1: " ;
getline(cin,in) ;
while(in != "") {
++rowLen ;
stringstream iss(initial) ;
while(iss >> rowarr[idx]) {
++idx ;
}
if(firstRow) {
colLen = idx ;
firstRow = 0 ;
}
cout << "Enter row " << rowLen + 1 << ": " ;
getline(cin,in) ;
}
idx = 0 ;
rows = rowLen ;
cols = colLen ;
arr = new double*[rows] ;
for(int i = 0; i < rows; ++i) {
arr[i] = new double[cols] ;
}
idx = 0 ;
for(int i = 0; i < rows; ++i) {
for(int j = 0; j < cols; ++j) {
arr[i][j] = rowarr[idx] ;
++idx ;
}
}
}
Main function:
#ifndef HEADER_H
#define HEADER_H
#include "header.h"
int main() {
clMatrix *aMatrix ;
clMatrix *bMatrix ;
aMatrix = new clMatrix ;
bMatrix = new clMatrix ;
char matrixId ;
int rowsA, rowsB, colsA, colsB ;
matrixId = 'A' ;
cout << "Matrix A input:\n" ;
aMatrix->userInput(matrixId,rowsA,colsA) ;
matrixId = 'B' ;
cout << "Matrix B input:\n" ;
bMatrix->userInput(matrixId,rowsB,colsB) ;
cout << "Matrix A output:\n" ;
cout << aMatrix ;
cout << "Matrix B output:\n" ;
cout << bMatrix ;
delete aMatrix ;
delete bMatrix ;
return 0 ;
}
When I run the program I get one, single heap-allocated address for each matrix and they are off by 32 bits I think? (My most recent run: 0x1dbcc20 and 0x1dbcc40). Would this mean that only my two integer member variables are being allocated for 16 bits each? If that's the case, is my memory allocation improper? I've also tried just about every possible gradation of dereferencing the double-type double pointer, but to no avail. Also, strangely the line:
os << "\nRow " << i+1 << ": " ;
from my stream insertion overload function never prints to console, despite it being intended to print for each row, yet the program skips it goes into the interior for loop and prints that one frickin' address. I simply don't understand.
I've run out of options (have been editing/recompiling/running and debugging in GDB/valgrind
for the last 5 hours), exhausted just about every resource I could find relevant to my problem, and so now at 2:45 AM, terribly sleep deprived I turn to you, the brave souls of SO. Any help is greatly appreciated, thank you! (So sorry if this is incoherent and hard to understand I'm very tired!)
Your stream-out operator has second formal parameter const clMatrix *&printMatrix
. This is an lvalue reference to a const pointer to clMatrix
. You're calling it with an lvalue non-const pointer to clMatrix
, which will not bind to the reference (if it did, you could use it to violate const safety).
As a result, the only available overload is the ostream
member function operator<<(const void* value)
, which prints a raw pointer value.
Either of the following signatures will work:
operator<<(ostream&, const clMatrix*const &)
operator<<(ostream&, const clMatrix*)
But it would be more idiomatic to take the clMatrix
parameter directly by const reference:
operator<<(ostream&, const clMatrix&)