Hey there, this is turning out to really be a tricky one for me.
main.cpp
#include <stdlib.h>
#include <iostream>
#include "Matrix.h"
int main(int argc, char** argv) {
// Dummy matrix
double row1[3] = {3, -1, -2};
double col1[3] = {4, 3, 1};
// Initialize matrix with 4 x 2 dimensions
Matrix<double> *m = new Matrix<double>(1, 3);
Matrix<double> *n = new Matrix<double>(3, 1);
Matrix<double> *mn;
// Set each row or column
m->set_row(row1, 0);
n->set_col(col1, 0);
std::cout << "Matrix M: \n";
m->print();
std::cout << "Matrix N: \n";
n->print();
std::cout << "Matrix MN: \n";
mn = m->mult(n);
mn->print();
return (EXIT_SUCCESS);
}
matrix.h
/*
* File: Matrix.h
* Author: charles
*
* Created on March 16, 2011, 12:45 AM
*/
#ifndef _MATRIX_H_
#define _MATRIX_H_
template <typename T>
class Matrix {
public:
Matrix(int _r, int _c){
// Set row and column size, then initialize matrix
_rows = _r;
_cols = _c;
_matrix = new T * [_rows];
for(int i = 0; i < _rows; ++i){
_matrix[i] = new T [_cols];
}
}
virtual ~Matrix(){
// Delete everything
for(int i = 0; i < _cols; ++i){
delete[] _matrix[i];
}
delete[] _matrix;
}
// Get number of rows
unsigned int get_rows(){
return _rows;
}
// Get number of columns
unsigned int get_cols(){
return _cols;
}
// Returns the row from _matrix as an array
T* get_row(int _r){
T* _t = new T [_cols];
for(int i = 0; i < _cols; ++i){
_t[i] = _matrix[_r][i];
}
return _t;
}
// Returns the column from _matrix as an array
T* get_col(int _c){
T* _t = new T [_rows];
for(int i = 0; i < _rows; ++i){
_t[i] = _matrix[i][_c];
}
return _t;
}
T get_elem(int _r, int _c){
return _matrix[_r][_c];
}
// Set a specific row with an array of type T
void set_row( T _t[], int _r ){
for(int i = 0; i < _cols; ++i){
_matrix[_r][i] = _t[i];
}
}
// Set a specific column with an array of type T
void set_col( T _t[], int _c){
for(int i = 0; i < _rows; ++i){
_matrix[i][_c] = _t[i];
}
}
// Set a specific index in the matrix with value T
void set_elem(T _t, int _r, int _c){
_matrix[_r][_c] = _t;
}
// Test to see if matrix is square
bool is_square(){
return (_rows == _cols);
}
// Print contents of matrix for debugging purposes
void print(){
for(int i = 0; i < _rows; ++i){
for(int j = 0; j < _cols; ++j){
std::cout << _matrix[i][j] << " ";
}
std::cout << "\n";
}
}
T comp_mult(int _r, T* _c){
T temp;
for(int i = 0; i < _cols; ++i){
std::cout << "Comp " << i << "\n";
if(i == 0) temp = _matrix[_r][i] * _c[i];
else temp += _matrix[_r][i] * _c[i];
}
return temp;
}
// Add one matrix to another and return new matrix
Matrix* add(Matrix* _m){
// Cannot add matrices if they do not have the same dimensions
if(!(_rows == _m->get_rows() && _cols == _m->get_cols())){
std::cout << "Not equal!";
return NULL;
}
else{
Matrix<T>* _t = new Matrix<T>(_rows, _cols);
for(int i = 0; i < _rows; ++i){
for(int j = 0; j < _cols; ++j){
_t->set_elem(_matrix[i][j] + _m->get_elem(i, j), i, j);
}
}
return _t;
}
}
// Multiply two matrices and return new matrix
Matrix* mult(Matrix* _m){
// If dimensions are not compatible return NULL
if(_cols != _m->get_rows()){
return NULL;
}
else{
Matrix<T>* _t = new Matrix<T>(_rows, _m->get_cols());
// Print out dimensions
// std::cout << "Dimensions: r = " << _t->get_rows() << " c = " << _t->get_cols() << "\n";
// Each row of _t
for(int i = 0; i < _t->get_rows(); ++i){
// Each value in each row of _t
for(int j = 0; j < _t->get_cols(); ++j){
T temp; // Temp variable to hold value for _t[i][j]
// Each row in _matrix
std::cout << "Loop i:" << i << "\n";
temp = this->comp_mult(i, _m->get_col(j));
std::cout << "loop j: " << j << "\n";
std::cout << "TEMP = " << temp << "\n";
_t->set_elem(temp, i, j); // this is where i segfault
}
}
}
}
// Multiply entire matrix by number and return new matrix
Matrix* scalar(T _n){
Matrix<T>* _t = new Matrix<T>(_rows, _cols);
for(int i = 0; i < _rows; ++i){
for(int j = 0; j < _cols; ++j){
_t->set_elem(_matrix[i][j] * _n, i, j);
}
}
return _t;
}
private:
unsigned int _rows; // Number of rows
unsigned int _cols; // Number of columns
T** _matrix; // Actual matrix data
};
#endif /* _MATRIX_H_ */
Sample Output
Matrix M:
3 -1 -2
Matrix N:
4
3
1
Matrix MN:
Loop i:0
Comp 0
Comp 1
Comp 2
loop j: 0
TEMP = 7
Segmentation fault
So the problem I'm having is that I am getting a segmentation fault when trying to assign a new matrix a value. It does not make sense to me because I have initialized the new matrix that I am trying to assign a value, I know its size, I'm not trying to access memory outside the matrix, and I know that my temp variable has a value. Anyone with a suggestion?
You forgot to return _t from mult() - The debugger likely gives you an incorrect location for the crash you get when calling mn->print()
Also, get_col and get_row leaks memory, and you need to make a copy constructor and an assignment operator.
_t->set_elem(temp, i, j); // this is where i segfault
My sixth sense tells me that you're going out of index. Check out your index values! Are they within limit?
Implement set_elem() as:
void set_elem(T _t, int _r, int _c){
if ( _ r >= _rows || _c >= _cols )
throw std::out_of_range("index out of range");
_matrix[_r][_c] = _t;
}
Related
I'm trying to split a matrix given into 4, but I'm getting some errors and I can't figure out why. I'm kind of new to the language. Does anybody knows what am I doing wrong?
void split_tl(T **matrice, unsigned int dim){
if(dim == 1){
return;
}
T **tl = new T*[dim/4];
for(unsigned int i = 0; i<dim/4;++i){
tl[i] = new T[dim/4];
}
for(unsigned int i=0; i<dim;++i){
for(unsigned int j=0; j<dim;j++){
if((i<dim/2) && (j<dim/2)){
tl[i][j] = matrice[i][j];
} else{
std::cout << "no ";
}
}
std::cout << std::endl;
}
}
In this function I'm trying to obtain the top left corner of the matrix.
int **matrice = new int*[2];
for(unsigned int i = 0; i<2;++i){
matrice[i] = new int[2];
}
for(unsigned int i = 0; i<2;++i){
for(unsigned int j = 0; j<2;++j){
matrice[i][j] = i+j;
}
}
This is the matrix I'm sending. It is a 2x2 matrix, just for testing purposes.
These are the errors from Valgrind:
==133== Invalid read of size 8
==133== Invalid write of size 4
==133== Process terminating with default action of signal 11 (SIGSEGV)
==133== Access not within mapped region at address 0x0
If dim is the side of a matrix, allocating to a quarter matrix should be dim/2.
Below in the code you are using :
if((i<dim/2) && (j<dim/2)){
tl[i][j] = matrice[i][j];
}
here tl may exceed the allocation
What you're doing wrong? You're allocating memory and passing pointers around.
Build a proper matrix class, e.g. (very simplified version):
template <typename T, unsigned Rows, unsigned Cols>
struct generic_matrix {
using datatype = T;
static constexpr unsigned rows = Rows;
static constexpr unsigned cols = Cols;
datatype data[rows][cols];
constexpr datatype& operator()(unsigned row, unsigned col) noexcept
{ return data[row][col]; }
constexpr const datatype& operator()(unsigned row, unsigned col) const noexcept
{ return data[row][col]; }
};
Submatrix:
/* Returns a submatrix of the matrix m,
* by deleting the row r and the column c.*/
template <typename M>
auto submatrix(const M& m, unsigned r, unsigned c) noexcept
{
generic_matrix<typename M::datatype, M::rows-1, M::cols-1> res;
for (unsigned row = 0, i = 0; row < M::rows; ++row) {
if (row == r) continue; //this row we do not want
for (unsigned col = 0, j = 0; col < M::cols; ++col) {
if (col == c) continue; //this col we do not want
res(i,j) = m(row,col);
++j;
}
++i;
}
return res;
}
Print:
template <typename M>
void printmatrix(const M& m) noexcept
{
for (unsigned r=0; r < M::rows; ++r) {
for (unsigned c=0; c < M::cols; ++c) {
std::cout << m(r,c) << ' ';
}
std::cout << '\n';
}
}
Test:
int main()
{
int n=0;
generic_matrix<int, 3, 3> m;
for (int r = 0; r < 3; ++r)
for (int c = 0; c < 3; ++c)
m(r,c) = ++n;
printmatrix(m);
std::cout << '\n';
printmatrix(submatrix(m, 0, 0));
std::cout << '\n';
printmatrix(submatrix(m, 1, 1));
std::cout << '\n';
printmatrix(submatrix(m, 2, 2));
return 0;
}
Note: It is just a hint. As you can see, no allocation nor casting is needed.
I'm not so advanced in c++ yet, but I'm trying to perform clustering analysis,
the data, vector< vector< double>> X, is M by T, with M features and T data points, I'm trying to group features into sets in which the distance correlation between each of the features within the set is above a certain threshold. The distCorrelation function is already defined by the way.
set<vector<double>> clusterIndices(vector<vector<double>> &X, double threshold){
vector<double> feature[X.size()];
for(int i = 0; i < X.size(); i++){
for(int j = 0; j < X[0].size(); j++){
feature[i].push_back(X[i][j]);
}
}
vector<vector<double>> distCorrMatrix(X.size(), vector<double> (X.size()));
for (int i = 0; i < X.size(); i++){
for (int j = 0; j < X.size(); j++){
distCorrMatrix[i][j] = (distCorrelation(feature[i],feature[j]) >= threshold ? 1.0 : 0.0);
}
}
set<vector<double>> rows;
for (int i = 0; i < X.size(); i++){
vector<int> temp;
for (int j = 0; j < X.size(); j++){
if (distCorrMatrix[i][j] == 1){
temp.push_back(j);
}
}
rows.insert(temp);
}
return rows;
}
So the above code will produce sets of features with mutually high correlation but will only give indices of those features.
That is, the returned rows could be (1,2,5) , (3,7,8,10) ... etc which translates to (feature[1],feature[2],feature[5]) , (feature[3],feature[7],feature[8],feature[10]) ...etc in which feature[i] represents i'th row of the data matrix.
The problem is I don't know how I can create a function that turns those each sets into matrices and return them.
No, your code won't compile. You should do it like this:
// k is the number of clusters
vector<vector<vector<double> > > myFunction(vector<vector<double> > &X, int k) {
vector<vector<vector<double> > > result(k);
for (int i = 0; i < X.size(); i++){
//do something then know X[i] belongs to cluster j
result[j].push_back(X[i]);
}
return result;
}
From what I can tell, you want this
std::vector<int> myclusteringfunction(std::vector<std::vector<double> > const &dataitems)
{
/* assign a cluster id to each data item */
std::vector<int> answer;
for(i=0;i<dataitems.size();i++)
answer.push_back( /* get the cluster id for each data item */);
/* return the ids as a list of the same length as your input list
eg {0, 1, 2, 1, 1, 1, 2, 2, 0, 0, 3, 1, 1, 1, 1} for four clusters */
return answer;
}
Your input seems unclear, but we can go this way: (check function getVectorOfMatrices)
#include <vector>
#include <iostream>
/**
* A classic 2D matrix implementation.
* Pay attention to the constructors and the operator=.
*/
class Matrix2D {
public:
// Standard constructor, allocates memory and initializes.
Matrix2D(const unsigned int rows, const unsigned int columns)
: m_rows(rows), m_columns(columns) {
m_data = new float*[rows];
for(unsigned row = 0; row < rows; ++row) {
m_data[row] = new float[columns];
for (unsigned column = 0; column < columns; ++column) {
m_data[row][column] = 0;
}
}
}
// Copy-constructor - also allocates and initializes.
Matrix2D(const Matrix2D& rhs) {
m_rows = rhs.m_rows;
m_columns = rhs.m_columns;
m_data = new float*[rhs.m_rows];
for (unsigned row = 0; row < rhs.m_rows; ++row) {
m_data[row] = new float[rhs.m_columns];
for (unsigned column = 0; column < rhs.m_columns; ++column) {
m_data[row][column] = rhs.at(row, column);
}
}
}
// Affectation operator - also allocates memory and initializes.
Matrix2D& operator=(const Matrix2D& rhs) {
m_rows = rhs.m_rows;
m_columns = rhs.m_columns;
m_data = new float*[rhs.m_rows];
for (unsigned row = 0; row < rhs.m_rows; ++row) {
m_data[row] = new float[rhs.m_columns];
for (unsigned column = 0; column < rhs.m_columns; ++column) {
m_data[row][column] = rhs.at(row, column);
}
}
}
// Used to set values in the 2D matrix
// NOTA : This function should check row vs m_rows and column vs m_columns
float& at(const unsigned int row, const unsigned int column) {
return m_data[row][column];
}
// Used to get values of the 2D matrix
// NOTA : This function should check row vs m_rows and column vs m_columns
const float at(const unsigned int row, const unsigned int column) const {
return m_data[row][column];
}
// Debug tool - prints the matrix
void print() const {
for (unsigned row = 0; row < m_rows; ++row) {
for (unsigned column = 0; column < m_columns; ++column) {
std::cout << " " << m_data[row][column] << " ";
}
std::cout << std::endl;
}
}
// Destructor - deallocates the memory
~Matrix2D() {
for (unsigned int row=0; row<m_rows; ++row) {
delete[] m_data[row];
}
delete[] m_data;
}
private:
unsigned int m_rows; // y-size
unsigned int m_columns; // x-size
float** m_data; // the data
};
/*
* Function that creates and returns a vector of 2D matrices
* Matrices are of different sizes
*/
std::vector<Matrix2D> getVectorOfMatrices() {
Matrix2D m1(1,1);
Matrix2D m2(2,2);
Matrix2D m3(3,3);
Matrix2D m4(4,2);
m1.at(0, 0) = 4;
m2.at(0, 1) = 2;
m4.at(1, 1) = 8;
std::vector<Matrix2D> result;
result.push_back(m1);
result.push_back(m2);
result.push_back(m3);
result.push_back(m4);
return result;
}
/*
* Main - simply call our function.
*/
int main () {
std::vector<Matrix2D> vec = getVectorOfMatrices();
for(std::vector<Matrix2D>::iterator it = vec.begin(); it != vec.end(); ++it) {
it->print();
}
return 0;
}
I have a 2D array and I want to define a function that returns the value of the index that the user gives me using operator overloading.
In other words:
void MyMatrix::ReturnValue()
{
int row = 0, col = 0;
cout << "Return Value From the last Matrix" << endl;
cout << "----------------------------------" << endl;
cout << "Please Enter the index: [" << row << "][" << col << "] =" << ((*this).matrix)[row][col] << endl;
}
The operation ((*this).matrix)[row][col] should return an int.
I have no idea how to build the operator [][].
Alternatively, I could concatenate a couple of calls to the operator [], but I didn't succeed in it, because the first call to that operaror will return int* and the second one will return int, and it compel to build another operator, and I dont want to do that.
The data matrix is defined like
int** matrix; matrix = new int*[row];
if (matrix == NULL)
{
cout << "Allocation memory - Failed";
}
for (int i = 0; i < row; i++)//Allocation memory
{
matrix[i] = new int[col];
if (matrix[i] == NULL)
{
cout << "Allocation memory - Failed";
return;
}
}
What can I do?
Thank you,
Simply, such an operator does not exist, so you can not overload it.
A possible solution is to define two classes: the Matrix and the Row.
You can define the operator[] of a Matrix so that it returns a Row, then define the same operator for the Row so that it returns an actual value (int or whatever you want, your Matrix could be also a template).
This way, the statement myMatrix[row][col] will be legal and meaningful.
The same can be done in order to assign a new Row to a Matrix or to change a value in a Row.
* EDIT *
As suggested in the comments, also you should take in consideration to use operator() instead of operator[] for such a case.
This way, there wouldn't be anymore the need for a Row class too.
You can define your own operator [] for the class. A straightforward approach can look the following way
#include <iostream>
#include <iomanip>
struct A
{
enum { Rows = 3, Cols = 4 };
int matrix[Rows][Cols];
int ( & operator []( size_t i ) )[Cols]
{
return matrix[i];
}
};
int main()
{
A a;
for ( size_t i = 0; i < a.Rows; i++ )
{
for ( size_t j = 0; j < a.Cols; j++ ) a[i][j] = a.Cols * i + j;
}
for ( size_t i = 0; i < a.Rows; i++ )
{
for ( size_t j = 0; j < a.Cols; j++ ) std::cout << std::setw( 2 ) << a[i][j] << ' ';
std::cout << std::endl;
}
}
The program output is
0 1 2 3
4 5 6 7
8 9 10 11
I have no idea how to build the operator [][].
Sometimes it is fine to use a different operator, namely ():
int& Matrix::operator () (int x, int y)
{
return matrix[x][y];
}
const int& Matrix::operator () (int x, int y) const
{
return matrix[x][y];
}
int diagonal (const Matrix& m, int x)
{
return m (x, x); // Usage.
}
Advantage:
No need to use "intermediate" class like Row or Column.
Better control than with Row& Matrix operator (int); where someone could use the Row reference to drop in a row of, say, illegal length. If Matrix should represent a rectangular thing (image, matrix in Algebra) that's a potential source of error.
Might be less tedious in higher dimensions, because operator[] needs classes for all lower dimensions.
Disadvantage:
Uncommon, different syntax.
No more easy replacement of complete rows / columns, if that's desired. However, replacing columns is not easy, anyway, provided you used rows to model (and vice versa).
In either case, there are pros and cons if the number of dimensions are not known at runtime.
I was looking for self-tested array replacement...
Improved version returns reference or NULL reference and checks boundaries inside.
#include <iostream>
#include <iomanip>
template<typename T, int cols>
class Arr1
{
public:
Arr1(T (&place)[cols]) : me(place) {};
const size_t &Cols = cols;
T &operator [](size_t i)
{
if (i < cols && this != NULL) return me[i];
else {
printf("Out of bounds !\n");
T *crash = NULL;
return *crash;
}
}
private:
T (&me)[cols];
};
template<typename T, int rows, int cols>
class Arr2
{
public:
const size_t &Rows = rows;
const size_t &Cols = cols;
Arr2() {
ret = NULL;
for (size_t i = 0; i < rows; i++) // demo - fill member array
{
for (size_t j = 0; j < cols; j++) matrix[i][j] = cols * i + j;
}
}
~Arr2() {
if (ret) delete ret;
}
Arr1<T, cols>(&operator [](size_t i))
{
if (ret != NULL) delete ret;
if (i < rows) {
ret = new Arr1<T, cols>(matrix[i]);
return *ret;
}
else {
ret = NULL;
printf("Out of bounds !\n");
return *ret;
}
}
//T(&MemberCheck)[rows][cols] = matrix;
private:
T matrix[rows][cols];
Arr1<T, cols> *ret;
};
template<typename T,int rows, int cols>
class Arr
{
public:
const size_t &Rows = rows;
const size_t &Cols = cols;
T(&operator [](size_t i))[cols]
{
if (i < rows) return matrix[i];
else {
printf("Out of bounds !\n");
T(*crash)[cols] = NULL;
return *crash;
}
}
T (&MemberCheck)[rows][cols] = matrix;
private:
T matrix[rows][cols];
};
void main2()
{
std::cout << "Single object version:" << endl;
Arr<int, 3, 4> a;
for (size_t i = 0; i <= a.Rows; i++)
{
int *x = &a[i][0];
if (!x) printf("Fill loop - %i out of bounds...\n", i);
else for (size_t j = 0; j < a.Cols; j++) a[i][j] = a.Cols * i + j;
}
for (size_t i = 0; i < a.Rows; i++)
{
for (size_t j = 0; j <= a.Cols; j++) {
std::cout << std::setw(2) << a[i][j] << ' ';
if (a.MemberCheck[i][j] != a[i][j])
printf("Internal error !");
}
std::cout << std::endl;
}
std::cout << endl << "Double object version:" << endl;
Arr2<int, 3, 4> a2;
for (size_t i = 0; i < a2.Rows; i++)
{
for (size_t j = 0; j <= a2.Cols; j++) {
int &x = a2[i][j];
if (&x)
{
x++;
std::cout << std::setw(2) << a2[i][j] << ' ';
//if (&a2.MemberCheck[i][j] != &a2[i][j])
// printf("Internal error !");
}
}
}
}
Output
Single object version:
Out of bounds !
Fill loop - 3 out of bounds...
0 1 2 3 4
4 5 6 7 8
8 9 10 11 -858993460
Double object version:
1 2 3 4 Out of bounds !
5 6 7 8 Out of bounds !
9 10 11 12 Out of bounds !
it works fine in the program below
#include<iostream>
using namespace std;
class A{
public:
int r,c;
int** val;
A()
{
r=0;c=0;val=NULL;
}
A(int row,int col)
{
r=row;c=col;
int count=0;
val=new int*[row];
for(int i=0;i<r;i++){
val[i]=new int[col];
for(int j=0;j<c;j++){
count++;
val[i][j]=count;
}
}
}
int* &operator[](int index){
return val[index];
}
};
int main(void){
A a(3,3);
cout<<a[1][2];
return 0;
}
here, a[1][2] first computes a[1]-->which returns 2nd row as (int*) type
then it's read as (int*)[2] which returns 3rd element of that row.In short,
a[1][2]------>(a[1])[2]------>(val[1])[2]------>val[1][2].
The following code is giving me the following error
Error description :
Unhandled exception at 0x00DC5D81 in ImageComponent2.exe: 0xC0000005: Access violation reading location 0xCDCDCDD5.
// ImageComponents
#include <iostream>
#include "Position.h"
using namespace std;
void labelComponents(int size, int **pixel);
void outputImage(int size, int **pixel);
int main(){
int size = 0;
cout << "Enter image size: ";
cin >> size;
int ** pixel = new int *[size + 2];
for (int i = 1; i <= size; i++)
{
pixel[i] = new int[size + 2];
}
cout << "Enter the pixel array in row-major order:\n";
for (int i = 1; i <= size; i++)
for (int j = 1; j <= size; j++)
{
cin >> pixel[i][j];
}
labelComponents(size, pixel);
outputImage(size, pixel);
system("pause");
return (0);
}
void labelComponents(int size, int **pixel){
// initialize offsets
Position * offset = new Position[4];
offset[0] = Position(0, 1); // right
offset[1] = Position(1, 0); // down
offset[2] = Position(0, -1); // left
offset[3] = Position(-1, 0); // up
int numNbr = 4; // neighbors of a pixel position
Position * nbr = new Position(0, 0);
Position * Q = new Position[size * size];
int id = 1; // component id
int x = 0; // (Position Q)
// scan all pixels labeling components
for (int r = 1; r <= size; r++) // row r of image
for (int c = 1; c <= size; c++) // column c of image
{
if (pixel[r][c] == 1)
{// new component
pixel[r][c] = ++id; // get next id
Position * here = new Position(r, c);
do
{// find rest of component
for (int i = 0; i < numNbr; i++)
{// check all neighbors of here
nbr->setRow(here->getRow() + offset[i].getRow());
nbr->setCol(here->getCol() + offset[i].getCol());
if (pixel[nbr->getRow()][nbr->getCol()] == 1)
{// pixel is part of current component
pixel[nbr->getRow()][nbr->getCol()] = id;
Q[x] = *nbr;
x++;
}
}
// any unexplored pixels in component?
*here = Q[x]; // a component pixel
x--;
} while (here != NULL);
} // end of if, for c, and for r
}
} // end of labelComponents
void outputImage(int size, int **pixel){
cout << "The labeled image is: ";
for (int i = 1; i <= size; i++){
cout << endl;
for (int j = 1; j <= size; j++)
cout << pixel[i][j] << " ";
}
} // end of outputImage
//Position.h
#ifndef POSITION_H
#define POSITION_H
class Position
{
private:
int row; // row number of the position
int col;
// column number of the position
public:
Position(); // default
Position( int theRow, int theCol); // parameter
Position(const Position & aPosition); // copy
Position & operator = (const Position & aPosition); // overload =
// overload =
// mutators
void setRow (int r);
void setCol (int c);
//accessors
int getRow() const;
int getCol() const;
}; // end Position
Position::Position()
{
setRow(0);
setCol(0);
}
Position::Position(int r, int c)
{
setRow(r);
setCol(c);
}
Position::Position(const Position & aPosition)
{
setRow(aPosition.row);
setCol(aPosition.col);
}
Position & Position::operator=(const Position & aPosition)
{
this->row=aPosition.row;
this->col=aPosition.col;
return(*this);
}
void Position::setRow(int r)
{
this->row = r;
}
void Position::setCol(int c)
{
this->col = c;
}
int Position::getRow() const
{
return this->row;
}
int Position::getCol() const
{
return this->col;
}
#endif
In C/C++, arraw indexes go from 0 to n-1, not from 1 to n. All your for loops are wrong:
for (int i = 1; i <= size; i++)
Must be replaced by:
for (int i = 0; i < size; i++)
Else, you access array at sizeposition which is out of bound.
Using a debugger and/or working with smaller piece of code would have made it easier for you to figure this out ;-)
I'm trying to figure out why my program fails when I run. So far when I run my program it fails on me. I debugged the error and it brings me to dbgdel.cpp. Line 32 " _ASSERTE(_BLOCK_TYPE_IS_VALID(pHead->nBlockUse));". I've searched for the answer to no avail, but it has something to do with my memory leak?
Here is my header:
#include <iostream>
using namespace std;
namespace project
{
#ifndef MATRIX_H
#define MATRIX_H
typedef int* IntArrayPtr;
class Matrix
{
public:
friend ostream& operator<<(ostream& out, Matrix& object);
//friend istream& operator>>(istream& in, Matrix& theArray);
//Default Constructor
Matrix();
Matrix(int max_number_rows, int max_number_cols, int intial_value);
//Destructor
~Matrix();
//Copy Constructor
Matrix(const Matrix& right_side);
//Assignment Operator
Matrix& operator=(const Matrix& right_side);
void Clear();
int Rows();
int Columns();
bool GetCell(int x,int y, int& val);
bool SetCell(int x,int y, int val);
int getNumber(int r, int c);
//void Debug(ostream& out);
private:
int initialVal;
int rows;
int cols;
IntArrayPtr *m;
};
#endif
}
My implementation file:
#include <iostream>
#include "Matrix.h"
using namespace project;
using namespace std;
namespace project
{
Matrix::Matrix()
{
typedef int* IntArrayPtr;
IntArrayPtr *m = new IntArrayPtr[1];
for(int i = 0; i < 1; i++)
m[i] = new int[1];
for(int r = 0; r < 1; r++)
for(int c = 0; c < 1;c++)
m[r][c] = 0;
}
Matrix::Matrix(int max_number_rows, int max_number_cols, int initial_value)
{
initialVal = initial_value;
rows = max_number_rows;
cols = max_number_cols;
IntArrayPtr *m = new IntArrayPtr[rows];
for(int i = 0; i < rows; i++)
m[i] = new int[cols];
for(int r = 0; r < max_number_rows; r++)
for(int c = 0; c < max_number_cols;c++)
m[r][c] = initial_value;
}
Matrix::~Matrix()
{
for(int i = 0; i <= rows; i++)
delete [] m[i];
delete [] m;
}
void Matrix::Clear()
{
for(int r = 0; r < rows; r++)
for(int c = 0; c < cols;c++)
m[r][c] = initialVal;
}
int Matrix::Rows()
{
return rows;
}
int Matrix::Columns()
{
return cols;
}
bool Matrix::GetCell(int x,int y, int& val)
{
if(x < rows || y < cols)
return false;
else
{
val = m[x - 1][y - 1];
return true;
}
}
bool Matrix::SetCell(int x, int y, int val)
{
if(x < rows || y < cols)
return false;
else
{
m[x - 1][y - 1] = val;
return true;
}
}
int Matrix::getNumber(int r, int c)
{
return m[r][c];
}
ostream& operator<<(ostream& out, Matrix& object)
{
for(int r = 0; r < object.rows; r++)
{
for(int c = 0; c < object.cols; c++)
{
out << " " << object.m[r][c];
}
out << endl;
}
return out;
}
Matrix& Matrix::operator=(const Matrix& right_side)
{
if (this != &right_side)
{
rows = right_side.rows;
cols = right_side.cols;
delete[] m;
IntArrayPtr *m = new IntArrayPtr[rows];
for(int i = 0; i < rows; i++)
m[i] = new int[cols];
for(int r = 0; r < rows; r++)
for(int c = 0; c < cols;c++)
m[r][c] = right_side.initialVal;
}
return *this;
}
/*
void Matrix::Debug(ostream& out)
{
out << "Number of rows = " << rows << endl;
out << "Number of columns = " << cols << endl;
out << "Initializer = " << initialVal << endl;
out << "Current contents of the matrix: " << endl;
out << m << endl;
}
*/
/*
istream& operator >>(istream& in, Matrix& theArray)
{
in >>
}
void interfaceMatrix()
{
int userChoice, rows, columns, value;
cout << "Default matrix or custom(1 for default, 0 for custom): ";
cin >> userChoice;
if (userChoice == 1)
{
Matrix object;
return object;
}
else if(userChoice == 0)
{
cout << "Enter number of rows: ";
cin >> rows;
cout << "Enter number of columns: ";
cin >> columns;
cout << "Enter initial value of each element: ";
cin >> value;
if(rows <= 0 || columns <= 0)
{
cout << "Invalid input." << endl;
exit(1);
}
else
{
Matrix object(rows, columns, value);
return object;
}
}
else
{
cout << "Invalid choice." << endl;
exit(1);
}
}
*/
}
In my driver I just put Matrix test(2,2,2), so I can create a 2 x 2 array with initial value of 2 for each element. I get the above error.
You are allocating rows number of rows, but deallocating rows+1 number of rows.
Check the destructor. <= must be <.
Besides this there are a lot of other [potential] errors in your code:
you are setting the local m variable instead of setting the m data member of your class (that's why I have the convention to always precede data members by m_ to prevent this kind of confusion). This error appears both in the constructor and the assignment operator.
you use rows to allocate the matrix, but max_number_rows to initialize the matrix. Although it works correctly now, it may lead to errors if row is initialized differently later (e.g. if row is initialized with std::max(max_number_rows,1000). Your code in the assignment operator is better.
your if-test in GetCell and SetCell is incorrect. It should probably be >= instead of <
the assignment operator copies the size of the matrix, but assigns all cells an initialValue. This is not an assignment. This implementation might/will confuse the rest of the code.
the typedef of IntArrayPtr is unnecessary
two issues:
You are not allocating any value into the "m" member of your object, you are allocating into local variables named "m"
you are over deallocating by looping from i=0 to i <= rows, you want i=0 to i < rows