c++ debug '<<' no operator found - c++

I am trying to run the following code on c++ but keep geting error. Can anyone solve it for me please.
the error message from c++ says:
Error 6 error C2679: binary '<<' : no operator found which takes a
right-hand operand of type 'MVector'
#include <iostream>
#include <cmath>
#ifndef MVECTOR_H // the 'include guard'
#define MVECTOR_H // see C++ Primer Sec. 2.9.2
#include <vector>
#include <string>
#include <fstream>
class MVector
{
public:
// constructors
MVector() {}
explicit MVector(int n) : v(n) {}
MVector(int n, double x) : v(n, x) {}
void push_back(double x)
{
v.push_back(x);
}
double AV()
{
double sum = 0.0, average = 0.0;
for (double i = 0; i<v.size(); i++)
{
sum += v[i];
}
average = sum / v.size();
return average;
}
MVector RunningAverage(int m, int p)
{
MVector movingaverage(v.size() - m - p - 1);
for (int i = m; i < v.size() - p; i++)
{
double sum = 0.0;
if ((i + p < v.size()))
{
for (int j = i - m; j <= i + p; j++)
{
sum += v[j];
movingaverage[i - m] = sum / (m + p + 1);
}
}
}
return movingaverage; // Edit by jpo38
}
// access element (lvalue)
double &operator[](int index) { return v[index]; }
// access element (rvalue)
double operator[](int index) const { return v[index]; }
int size() const { return v.size(); } // number of elements
private:
std::vector<double> v;
};
#endif
int main()
{
using namespace std;
// create an MVector
MVector x;
// add elements to the vector
x.push_back(1.3);
x.push_back(3.5);
x.push_back(3.0);
x.push_back(2.0);
// x now contains 1.3 and 3.5
// print x
std::cout << " x:= ( ";
for (int i = 0; i < x.size(); i++)
std::cout << x[i] << " ";
std::cout << ")\n";
std::cout << x.RunningAverage(0, 1.0) << endl;
return 0;
}

x.RunningAverage(0, 1.0) returns a MVector that cannot be sent to std::cout, unless you declare the operator<< taking a MVector as parameter.
Alternatively, you can replace:
std::cout << x.RunningAverage(0, 1.0) << endl;
By:
MVector av = x.RunningAverage(0, 1.0);
for (int i = 0; i < av.size(); i++)
std::cout << av[i] << " ";
Or, declare the operator:
std::ostream& operator<<(std::ostream& out,const MVector& b)
{
for (int i = 0; i < b.size(); i++)
out << b[i] << " ";
return out;
}
And then std::cout << x.RunningAverage(0, 1.0) << std::endl; will work.
And you can then also replace, in your main function:
for (int i = 0; i < x.size(); i++)
std::cout << x[i] << " ";
By:
std::cout << x;
Live demo: http://cpp.sh/7afyi

You haven't overloaded operator<< for MVector.
You can do that with:
std::ostream& operator<<(std::ostream& output, MVector const& vec)
{
// use "output << …;" to do printing
return output;
}

Related

Overloading Operator *= and Operator+ in Matrix Template Class

The method template <class T> const Matrix<T> &Matrix<T>::operator*=(T rhs) for program matrix.cc should be able to returns calling object with matrix scaled by rhs, and the parameter rhs will be the same type as the matrix.
The error output that I am receiving from the compiler is:
[hw7] make clean && make bin/test_matrix_mul_assign && ./bin/test_matrix_mul_assign
rm -f bin/*
g++ -std=c++11 -Wall -I inc -I src -c src/test_matrix_mul_assign.cc -o bin/test_matrix_mul_assign.o
g++ bin/test_matrix_mul_assign.o -o bin/test_matrix_mul_assign
Testing Matrix::operator*=
Expected Matrix[0][0]: 2.0, Actual: 1
FAILED
Could someone let me know why I receive this "Failed" output when I know I pass the // TEST MUL ASSIGMENT OP CORRECT RETURN section.
Here is my matrix.cc:
#include <matrix.h>
template <class T>
const Matrix<T> &Matrix<T>::operator*=(T rhs) {
unsigned int rows_ = 0;
unsigned int cols_ = 0;
T **m_ = nullptr;
for (unsigned int i = 0; i < rows_; ++i) {
m_[i] = new T[cols_];
for (unsigned int j = 0; j < cols_; ++j) {
m_[i][j] = m_[i][j] * rhs;
}
}
return *this;
}
template <class T>
const Matrix<T> Matrix<T>::operator+(const Matrix<T> &rhs) const {
if (!(this->cols_ == rhs.cols_) && (this->rows_ == rhs.rows_)) {
std::cout << "Cannont add matrices. Wrong dimensions\n";
exit(0);
}
Matrix<T> lhs;
lhs.rows_ = this->rows_;
lhs.cols_ = this->cols_;
for (unsigned int i = 0; i < lhs.rows; ++i) {
for (unsigned int j = 0; j < lhs.cols_; ++j) {
lhs[i] += rhs[i];
}
}
return lhs;
}
Here is my matrix.h:
#include <cassert>
// using assert
#include <exception>
#include <iostream>
template <class T>
class Matrix {
public:
friend class MatrixTester;
/* Times Equals Op: 1 Point
* Returns calling object with matrix scaled by rhs.
* Parameter:
* - rhs will be the same type as the matrix
*/
const Matrix<T> &operator*=(T rhs);
/* Add Op: 1 Point
* Returns the sum of calling object's matrix and rhs's matrix as a new
* object.
* Precondition(s):
* - lhs rows must equal rhs rows
* - lhs cols must equal rhs cols
*/
const Matrix<T> operator+(const Matrix<T> &rhs) const;
private:
T **m_;
unsigned int rows_;
unsigned int cols_;
};
#include <matrix.cc> //NOLINT
This is my test_matrix_mul_assign.cc tester:
#include <test_matrix.h>
int main(int argc, char **argv) {
MatrixTester tester;
cout << "Testing Matrix::operator*=" << endl;
if (tester.Test_MulAssignOp()) {
cout << " PASSED" << endl;
return 0;
}
cout << " FAILED" << endl;
return 1;
}
bool MatrixTester::Test_MulAssignOp() const {
const int kRows = 3, kCols = 4;
Matrix<double> test_m;
test_m.m_ = new double *[kRows];
for (unsigned int i = 0; i < kRows; ++i) {
test_m.m_[i] = new double[kCols];
for (unsigned int j = 0; j < kCols; ++j)
test_m.m_[i][j] = (i + 1.0) * (j + 1.0);
}
test_m.rows_ = kRows;
test_m.cols_ = kCols;
// TEST MUL ASSIGMENT OP CORRECT RETURN
const Matrix<double> *m_ptr = &(test_m *= 2.0);
if (m_ptr != &test_m) {
cout << " Expected return address of assigment: " << &test_m
<< ", Actual: " << m_ptr << endl;
return false;
}
// TEST MUL ASSIGMENT OP CALCULATION
if (test_m.m_[0][0] != 2.0) {
cout << " Expected Matrix[0][0]: 2.0, Actual: " << test_m.m_[0][0] << endl;
return false;
}
if (test_m.m_[1][3] != 16.0) {
cout << " Expected Matrix[1][3]: 16.0, Actual: " << test_m.m_[1][3]
<< endl;
return false;
}
if (test_m.m_[2][2] != 18.0) {
cout << " Expected Matrix[2][2]: 18.0, Actual: " << test_m.m_[2][2]
<< endl;
return false;
}
return true;
}
You have the following variable definitions in the operator*= implementation:
unsigned int rows_ = 0;
unsigned int cols_ = 0;
T **m_ = nullptr;
They will shadow all of the members of the class. When you use rows_, cols_ and m_ later in the function definition they will refer to these local variables, not the class members of the current instance.
Therefore effectively your implementation of operator*= does nothing at all. It is not surprising that the test for the correct value then fails.
Simply remove these declarations, so that the names will refer to the current instance's members instead.
Then there is also not going to be any point to m_[i] = new T[cols_];. So remove that as well.
Why are there all of these dynamic allocations with new in the first place? This is seriously bad style and is going to cause you all kinds of issues. Use std::vector instead.
class Matrix also seems to be lacking a proper constructor. This again will cause all kinds of issues, especially when it leaves memory allocation to a user of the class.

How to fix segmentation fault for C++?

I am getting a segmentation fault error when compiling my code. I don't know how to fix it. I am supposed to compile my Polynomial.cpp with my professor's poly_check.o, but I get a segmentation fault error.
This is my Polynomial.h:
#ifndef POLYNOMIAL_H
#define POLYNOMIAL_H
#include <iostream>
using namespace std;
class Polynomial {
private:
double *coefficients;
int size;
public:
Polynomial();
Polynomial(double c[], int size);
Polynomial(const Polynomial &poly);
~Polynomial();
void set(double c[], int size);
inline int getDegree() const {
return size - 1;
}
double f(double x)const;
bool operator== (const Polynomial &poly)const;
Polynomial operator+ (const Polynomial &poly)const;
friend ostream & operator << (ostream &out, const
Polynomial &poly);
friend istream & operator >> (istream &in, Polynomial
&poly);
};
#endif
This is my Polynomial.cpp:
#include "Polynomial.h"
#include <iostream>
#include <cmath>
using namespace std;
Polynomial::Polynomial() {
size = 0;
coefficients = NULL;
}
Polynomial::Polynomial(double c[], int size) {
this->size = size;
coefficients = new double[size];
for (int i = 0; i < size; i++) {
coefficients[i] = c[i];
}
}
Polynomial::Polynomial(const Polynomial &poly) {
if (coefficients != NULL)
delete coefficients;
this->size = poly.size;
coefficients = new double[size];
for (int i = 0; i < size; i++)
coefficients[i] = poly.coefficients[i];
}
Polynomial::~Polynomial() {
if (coefficients != NULL)
delete coefficients;
}
void Polynomial::set(double c[], int size) {
this->size = size;
if (coefficients != NULL)
delete coefficients;
coefficients = new double[size];
for (int i = 0; i < size; i++)
coefficients[i] = c[i];
}
double Polynomial::f(double x)const {
double value = 0.0;
for (int i = 0; i < size; i++) {
value += (coefficients[i] * pow(x, i));
}
return value;
}
bool Polynomial::operator== (const Polynomial &poly)const {
if (this->size != poly.size)
return false;
for (int i = 0; i < size; i++) {
if (poly.coefficients[i] != coefficients[i])
return false;
}
return true;
}
Polynomial Polynomial::operator+ (const Polynomial &poly)const {
int maxSize = size;
if (poly.size > maxSize)
maxSize = poly.size;
double sum[maxSize] = {0.0};
for (int i = 0; i < size; i++) {
sum[i] = coefficients[i];
}
for (int i = 0; i < poly.size; i++) {
sum[i] += poly.coefficients[i];
}
Polynomial sumP(sum, maxSize);
return sumP;
}
ostream &operator << (ostream &out, const Polynomial &poly) {
for (int i = poly.size - 1; i >= 0; i--) {
if (i != poly.size - 1) {
if (poly.coefficients[i] >= 0)
out << " + ";
else
out << " - ";
}
out << poly.coefficients[i];
if (i == 0)
continue;
if (i == 1)
out << "x";
else
out << "x^" << i;
}
return out;
}
istream &operator >> (istream &in, Polynomial &poly) {
int degree;
in >> degree;
double c[100];
int size = 0;
while (in >> c[size]) {
size++;
if ((size-1) == degree)
break;
}
poly.set(c, size);
return in;
}
This is my poly_test.cpp:
#include "Polynomial.h"
#include <iostream>
using namespace std;
int main(void) {
double c1[] = {0, 1, 2, 3, 4};
double c2[] = {0, 1, 2, 3, 4, 5, 6};
Polynomial p1(c1, 5);
Polynomial p2(c2, 7);
Polynomial p3;
cout << "Enter p3: ";
cin >> p3;
cout << "p1: ";
cout << p1 << endl;
cout << "p2: ";
cout << p2 << endl;
cout << "p3: ";
cout << p3 << endl;
Polynomial p4;
p4 = p1 + p2;
cout << "p4 = p1 + p2, p4: ";
cout << p4 << endl;
double value = p1.f(2);
cout << "Evaluating p1 at x = 2, p1 = ";
cout << value << endl;
Polynomial p6(c1, 5);
cout << "p6: ";
cout << p6 << endl;
if (p6 == p1) {
cout << "p6 and p1 are equal. Equality test passed" <<
endl;
}
else {
cout << "Equality test failed" << endl;
}
return 0;
}
This is the error that I am getting:
segmentation fault error
In general, you should test your own code as you develop it. Don't write this much code and then plug it into a test function; it will fail, and the process of debugging it will be long and discouraging.
The specific problem (or one of them) is that you neglected to implement operator=. Are you familiar with shallow copies and deep copies? The default copy constructor is a shallow copier, so that two instances of Polynomial wind up with pointers to the same array. Then when they die, they both try to delete it.

What's wrong with ADT constructor for SquareMatrix?

This project I am writing in order to create a Square Matrix ADT object has a problem with the constructor (not the default constructor). I have traced the problem back to the constructor but I cannot figure out what is wrong with it which makes it crash everytime I try to run my test in main.cpp.
I usually get an error that say something along the lines "Thread 1: EXC_BAD_ACCESS: ..." and the console usually says "(11db)"
Does anyone have any ideas on what might be causing all the problems?
This is the header file:
#include <iostream>
#include <vector>
using namespace std;
#ifndef SquareMatrix_h
#define SquareMatrix_h
class SquareMatrix {
private:
vector<vector<double>> numMatrix;
public:
SquareMatrix();
SquareMatrix(vector<vector<double>>& v2d);
double getValue(int x, int y);
void setValue(int x, int y, double value);
friend SquareMatrix operator * (SquareMatrix m1, SquareMatrix m2);
friend SquareMatrix operator - (SquareMatrix m1, SquareMatrix m2);
friend ostream& operator <<(ostream &out, SquareMatrix m);
};
#endif /* SquareMatrix_h */
This is my SquareMatrix.cpp file: (The constructor that I believe isn't working is the second function in the code: SquareMatrix::SquareMatrix(vector>& v2d) {...)
#include "SquareMatrix.h"
#include <iostream>
using namespace std;
SquareMatrix::SquareMatrix() {
numMatrix.clear();
for(int i = 0; i < 10; i++) {
vector<double> initial;
for(int j = 0; j < 10; j++) {
initial.push_back(0.0);
}
numMatrix.push_back(initial);
}
}
SquareMatrix::SquareMatrix(vector<vector<double>>& v2d) {
bool flagSize = true;
for(int i = 0; i < v2d.size(); i++) {
if(v2d[i].size() != v2d.size()) {
flagSize = false;
break;
}
}
if(flagSize) {
numMatrix.clear();
for(int i = 0; i < v2d.size(); i++) {
vector<double> initial;
for(int j = 0; j < v2d[i].size(); i++) {
initial.push_back(v2d[i][j]);
}
numMatrix.push_back(initial);
}
} else {
numMatrix.clear();
for(int i = 0; i < 10; i++) {
vector<double> initial;
for(int j = 0; j < 10; j++) {
initial.push_back(0.0);
}
numMatrix.push_back(initial);
}
}
}
double SquareMatrix::getValue(int x, int y) {
if((x < numMatrix.size()) && (y < numMatrix.size()) && (x >= 0) && (y >= 0)) {
return numMatrix[x][y];
}
return 0;
}
void SquareMatrix::setValue(int x, int y, double value) {
if((x < numMatrix.size()) && (y < numMatrix.size()) && (x >= 0) && (y >= 0)) {
numMatrix[x][y] = value;
}
}
SquareMatrix operator * (SquareMatrix m1, SquareMatrix m2) {
if(m1.numMatrix.size() == m2.numMatrix.size()) {
vector<vector<double>> result;
for(int i = 0; i < m1.numMatrix.size(); i++) {
vector<double> initial;
for(int j = 0; j < m1.numMatrix.size(); j++) {
initial.push_back(0);
}
result.push_back(initial);
}
for(int i = 0; i < m1.numMatrix.size(); i++) {
for(int j = 0; j < m1.numMatrix.size(); j++) {
result[i][j] = 0;
for (int a = 0; a < m1.numMatrix.size(); a++) {
result[i][j] += m1.numMatrix[i][a] + m2.numMatrix[a][j];
}
}
}
return SquareMatrix(result);
}
return SquareMatrix();
}
SquareMatrix operator - (SquareMatrix m1, SquareMatrix m2) {
if(m1.numMatrix.size() == m2.numMatrix.size()) {
vector<vector<double>> result;
for(int i = 0; i < m1.numMatrix.size(); i++) {
vector<double> initial;
for(int j = 0; j < m1.numMatrix[i].size(); j++) {
double pushNum = (m1.getValue(i,j) - m2.getValue(i,j));
initial.push_back(pushNum);
}
result.push_back(initial);
}
return SquareMatrix(result);
}
return SquareMatrix();
}
ostream& operator << (ostream &out, SquareMatrix m) {
out << "(";
for (int i = 0; i < m.numMatrix.size(); i++) {
for (int j = 0; j < m.numMatrix.size(); j++) {
out << " " << m.numMatrix[i][j];
if(j != (m.numMatrix.size() - 1)) {
out << ", ";
}
}
}
out << ")";
return out;
}
Then this is the main.cpp that I am using to test the SquareMatrix ADT object:
#include "SquareMatrix.h"
#include <iostream>
#include <random>
#include <ctime>
#include <vector>
using namespace std;
int main() {
srand(time(NULL));
vector<vector<double>> m1;
vector<vector<double>> m2;
int size = 0;
cout << "Enter the size of the Square Matrix: ";
cin >> size;
for (int i = 0; i < size; i++) {
vector<double> in1;
vector<double> in2;
for (int j = 0; j < size; j++) {
in1.push_back(rand() % 100);
in2.push_back(rand() % 100);
}
m1.push_back(in1);
m2.push_back(in2);
}
SquareMatrix res1 = SquareMatrix(m1);
SquareMatrix res2 = SquareMatrix(m2);
cout<< "\nMatrix 1: " << endl;
cout << res1 << endl;
cout<< "\nMatrix 2: " << endl;
cout << res2 << endl;
SquareMatrix mult = res1*res2;
cout << "\nMatrix1 * Matrix 2: " << endl;
cout << mult << endl;
SquareMatrix min1_2 = res1 - res2;
cout << "Matrix1 - Matrix 2: " << endl;
cout << min1_2 << endl;
SquareMatrix min2_1 = res2 - res1;
cout << "Matrix2 - Matrix 1: " << endl;
cout << min2_1 << endl;
return 0;
}
Any help you could give would be appreciated. :)
As pointed out in the comments, you problem is a simple typo in one of your nested loops. However, I'd like to add some recommendations to make your code less error prone (and also more readable).
Firstly, when iterating over all elements of a vector, unless you need an index for something else, you should be using a range-based for-loop. In your code, you might replace the check for square size with the following:
for (const vector<double>& vec: v2d){
if (vec.size() != v2d.size()){
flagSize = false;
break;
}
}
This expresses your intent a little more clearly, and, more importantly, prevents you from accidentally reading from/writing to a location out of your vector's bounds (accidentally typing <= instead of just < happens to the best of us).
Secondly, the two nested loops (that contained your error) can be replaced with a simple copy assignment (numMatrix = v2d; reference). Again, this expresses your intent in addition to being a whole lot shorter. No need to reinvent the wheel with functions like these.
The contents of the else-branch of the surrounding if-statement can also be replaced with a call to assign (the first overload listed on the page, use like numMatrix.assign(10, vector<double>(10, 0.0))). Like before, clearer expression of intent and avoidance of index errors.
Finally, the parameter in this constructor can be a const reference instead of a normal one since you do not alter its contents in any way (and, given this, it should be const).
You might wonder why "expression of intent" is relevant, or what it even means in this context. Essentially, it's all about making what you're trying to do immediately obvious to any reader. This is more important in large projects with many contributors but it is helpful even when debugging small applications like this one. You seem to be learning still, but I strongly believe it's a good thing to keep in mind from the beginning. After all, many of these changes also make for briefer code, making it that much easier for others to help you if you run into a problem.
I realize this left the scope of the original question somewhat, but I hope you find this helpful nonetheless.

vector subscript out of range when writing to file

I want to write a vector to a file, which represents the outcomes of a function that increments j with steps of "double Golf_dl".
The vector itself must have "int Golf_NL" elements in it. (Golf_dl is a private member of class Tsunami)
The problem is that I get a constant vector with all values equal to 0.5, which is rubbish.
Can someone see what's wrong?
Code:
void T_Tsunami::Toestand(int nl)
{
struct pb
{
std::vector<double>& v_;
pb(std::vector<double>& v)
: v_(v){};
pb& operator+(double i)
{
v_.push_back(i);
return *this;
}
};
for( double i = 0; i < nl; i++ )
{
double j=0;
double y = 0.25*(1-tanh(double(j-75)/5));
j+=Golf_dl;
pb(T_1)+y;
}
}
void T_Tsunami::Write(vector<double>d)
{
const int Naamgrootte=64;
char Naam[Naamgrootte];
std::cout << "Geef een bestandsnaam in" << std::endl;
std::cin >> Naam;
std::cout << std::endl;
std::ofstream outFile(Naam);
if (!outFile)
{
std::cerr << "Kan bestand niet openen" << std::endl;
exit (1);
}
for (int i=0; i<100; i++)
{
outFile << d[i] << std::endl;
}
outFile.close();
}
Your problem is in here:
for( double i = 0; i < nl; i++ )
{
double j=0;
double y = 0.25*(1-tanh(double(j-75)/5));
j+=Golf_dl;
pb(T_1)+y;
}
Consider the fact that the loop variable, i, is not used anywhere inside the loop. Also, j and y do not retain their values between loops (they are not static).

Operator overloading unhandled exception

I am having some trouble overloading the + operator. I get a runtime error. Unhandled exception followed by a memory address.
Below is what I have coded:
#include <iostream>
#include <iomanip>
using namespace std;
class myVector{
int vsize, maxsize;
int* array;
void alloc_new();
friend ostream& operator<< (ostream &out, myVector&);
friend istream& operator>> (istream &in, myVector&);
public:
myVector();
myVector(int);
myVector(const myVector&); //copy constructor
~myVector();
void push_back(int);
int size();
int operator[](int);
myVector operator+(myVector&);
int at(int i);
};
myVector::myVector()
{
maxsize = 20;
array = new int[maxsize];
vsize = 0;
}
myVector::myVector(int i)
{
maxsize = i;
array = new int[maxsize];
vsize = 0;
}
myVector::myVector(const myVector& v){}
myVector::~myVector()
{
delete[] array;
}
void myVector::push_back(int i)
{
if (vsize + 1 > maxsize)
alloc_new();
array[vsize] = i;
vsize++;
}
int myVector::operator[](int i)
{
return array[i];
}
int myVector::at(int i)
{
if (i < vsize)
return array[i];
throw 10;
}
void myVector::alloc_new()
{
maxsize = vsize * 2;
int* tmp = new int[maxsize];
for (int i = 0; i < vsize; i++)
tmp[i] = array[i];
delete[] array;
array = tmp;
}
int myVector::size()
{
return vsize;
}
myVector myVector::operator+(myVector& a)
{
myVector result;
for (int i = 0; i < a.size(); i++)
result.array[i] = this->array[i] + a.array[i];
return result;
}
ostream& operator<< (ostream &out, myVector& a)
{
for (int i = 0; i < a.size(); i++)
out << a[i] << " ";
return out;
}
istream& operator>> (istream &in, myVector& a)
{
int tmp, lol;
cin >> tmp;
for (int i = 0; i < tmp; i++)
{
cin >> lol;
a.push_back(lol);
}
return in;
}
int main()
{
myVector vec;
myVector vec2;
myVector c;
int width = 15;
cout << "Input vector a\n";
cin >> vec; // In: 3 1 2 3
cout << "Input vector b\n";
cin >> vec2; // In: 3 4 5 6
cout << setw(width) << "Vector a: " << vec << endl;
cout << setw(width) << "Vector b: " << vec2 << endl;
cout << setw(width) << "c = a + b: " << c << endl;
c = vec + vec2;
system("PAUSE");
return 0;
}
How would I go about writing a copy constructor for a dynamic array? This is what I have right now:
myVector::myVector(const myVector &initial)
{
int* tmp = new int[3];
for (int i = 0; i < 3; i++)
tmp[i] = initial.array[i];
delete[] array;
array = tmp;
}
When you're assigning the results in your operator+, you've done nothing to reserve space in the results vector.
(You should slather your class in runtime checks (assert or similar) to sanity-check all the inputs to every method. That would show you that your result indexer passed in an index which didn't exist in the vector.)