1

These are the files:

//============================================================================
// Name        : linearMatrix.hpp
// Author      : Flores, Facundo Gabriel
// Version     : 0.1
// Description : This file contains the linearMatrix class.
//===========================================================================

#ifndef LINEARMATRIX_HPP_
#define LINEARMATRIX_HPP_

class linearMatrix
{
public:
    //Constructor
    linearMatrix(const int Width, const int Heigth);

    //Destructor
    ~linearMatrix();

    //We read a matrix file
    void Read_File_Matrix(const char *Path);

    //We write a matrix file
    void Write_File_Matrix(const char *Path);

    //Generate a diagonal dominant matrix
    void Generate_Diagonal_Dominant(void);

    //Generate a random matrix
    void Generate_Random_Matrix(void);

    //Copy a float *vector
    void Copy_Vector(const float *V, const int Width, const int Heigth);

    //Show a little vector
    void Show_Little_Matrix(void);

private:
    int _Width, _Height; // Width and Height
    float* myVector;

    //Aux function for testing
    bool Test_Sizes(const int Width, const int Heigth);
};



#endif /* LINEARMATRIX_HPP_ */


//============================================================================
// Name        : linearMatrix.cpp
// Author      : Flores, Facundo Gabriel
// Version     : 0.1
// Description : This file contains the linearMatrix implementation class.
// A linear matrix is a vector that represents a matrix.
// We will read this kind of classes from files, because
// they are generally large. But linearMatrix can represent
// a 1D vector if Height is 1.
//============================================================================



#include <iostream>
using std::cout;
using std::endl;
using std::cerr;
using std::bad_alloc;

#include <cstdio>

#include <cstdlib>

#include <ctime>

#include <new>

#include "linearMatrix.hpp"


#define FALSE 0
#define TRUE 1

//Test if W and H are correct
bool linearMatrix::Test_Sizes(const int W, const int H)
{
    if(W < 1 || W > 32500)
        return FALSE;
    if(H < 1 || H> 32500)
        return FALSE;
    return TRUE;
}

// We set the Width and Height parameters
linearMatrix::linearMatrix(const int Width, const int Height)
{
    if(Test_Sizes(Width, Height))
    {
        _Width = Width;
        _Height = Height;
        try{
            myVector = new float[_Width * _Height];
        }
        catch(bad_alloc &ex)
        {
            cerr << "Exception:" << ex.what();
            exit(1);
        }
    }
    else
    {
        cout<<"Bad sizes!"<<endl;
        exit(1);
    }

}

linearMatrix::~linearMatrix()
{
    delete [] myVector;
}

//We set a random vector using its Width and Height
void linearMatrix::Generate_Random_Matrix(void)
{
    srand(time(NULL));
    for(int i = 0; i < _Width; i++)
        for(int j = 0; j < _Height; j++)
        {
            // We are putting a number between 0 and 99
            myVector[i * _Width + _Height] = rand() % 100;
        }
}

//We set a diagonal dominant matrix
void linearMatrix::Generate_Diagonal_Dominant(void)
{
    for(int i = 0; i < _Width; i++)
        for(int j = 0; j < _Height; j++)
        {
            if(i == j) //Diagonal item
                myVector[i * _Width + j] = 32500;
            else
                myVector[i * _Width + j] = 0.5;
        }
}

//We copy V into myVector
void linearMatrix::Copy_Vector(const float *V, const int Width, const int Heigth)
{
    if(Width != _Width || Heigth != _Height)
    {
        cout<<"Different sizes, we cannot copy vector V"<<endl;
        exit(1);
    }
    else
    {
        for(int i = 0; i < _Width; i++)
            for(int j = 0; j < _Height; j++)
            {
                myVector[i * _Width + j] = V[i * Width + j];
            }
    }
}

//We show a little matrix. Assume H < 11 and W < 11
void linearMatrix::Show_Little_Matrix(void)
{
    cout.precision(5);
    if(_Height < 11 && _Width < 11)
    {
        for(int i = 0; i < _Width; i++)
        {
            for(int j = 0; j < _Height; j++)
            {
                cout<<myVector[i * _Width + j]<<" ";
            }
            cout << endl;
        }
    }
    else
    {
        cout << "I can show only little matrices in the console " << endl;
    }
}

void linearMatrix::Write_File_Matrix(const char *Path)
{
    FILE *pFile = fopen(Path, "wb");
    fwrite(&_Height, sizeof(int), 1, pFile);
    fwrite(&_Width, sizeof(int), 1, pFile);
    fwrite(myVector, sizeof(float), _Height * _Width, pFile);
    fclose(pFile);
}

void linearMatrix::Read_File_Matrix(const char *Path)
{
    FILE *pFile = fopen(Path, "rb");
    if(pFile == NULL){
        cout << "Cannot read :" << Path << endl;
        exit(1);
    }
    fread(&_Height, sizeof(int), 1, pFile);
    fread(&_Width, sizeof(int), 1, pFile);

    try{
        myVector = new float[_Width * _Height];
    }
    catch(bad_alloc &ex)
    {
        cout << "Exception:" << ex.what();
        exit(1);
    }
    fread(myVector, sizeof(double), _Height * _Width, pFile);
}

And I'm trying to use this class with the following main.cpp:

//============================================================================
// Name        : main.cpp
// Author      : Flores, Facundo Gabriel
// Version     : 0.1
// Description : This file is a test.
//===========================================================================
#include <iostream>
#include "linearMatrix.hpp"

int main(void)
{
    linearMatrix Matrix2(3,1);

    Matrix2.Generate_Diagonal_Dominant();
    Matrix2.Show_Little_Matrix();

    return 0;
}

So the error is:

*** glibc detected *** /.../linearMatrix/Debug/linearMatrix: free(): invalid next size (fast): 0x00000000007f1010 ***

I don't know how to use valgrind yet. But why is the error there? The program shows me the correct output, but when the destructor is "executed" the error appears while freeing myVector. How to solve it?

Unihedron
  • 10,902
  • 13
  • 62
  • 72
FacundoGFlores
  • 7,858
  • 12
  • 64
  • 94
  • 1
    Identifiers starting with an underscore, followed by a capital letter, such as your `_Width`, are [reserved](http://stackoverflow.com/questions/228783/what-are-the-rules-about-using-an-underscore-in-a-c-identifier) in any scope. I would keep that in mind. You are also not giving any attention to the [Rule of Three](http://stackoverflow.com/questions/4172722/what-is-the-rule-of-three) (Five), which should really be the [Rule of Zero](http://rmartinho.github.com/2012/08/15/rule-of-zero.html) in this day and age. – chris Sep 08 '12 at 19:50
  • 1
    you should learn how to use valgrind and debugger as fast as possible. With valgrind basic command is: "valgrind --tool=memcheck --leak-check=yes --show-reachable=yes --num-callers=20 --track-fds=yes ./test" remember about debugger flag in your compiler, in g++ it is "-g". – CyberGuy Sep 08 '12 at 19:51
  • @chris. Identifiers starting with an underscore are members of the class linearMatrix. I will read about Rule of Three and Rule of Zero, I have never listened about them, thank you. – FacundoGFlores Sep 08 '12 at 19:54
  • @Mycotoxin thank you, I will try to learn valgrind as far as I can. – FacundoGFlores Sep 08 '12 at 19:54
  • @john Im sure, when I debug the application, I start in the linearMatrix declaration, after that I follow step by step the allocation, then the matrix generation, then showing matrix, and finally I debug return, and it goes to ~linearMatrix, and the error appears here. – FacundoGFlores Sep 08 '12 at 20:00
  • 1
    @facunvd, But what is meant by "any scope" is that a macro could be named `_Width`. If that happens in a future implementation change, your in-class `_Width` is still just as screwed. In comparison, identifiers starting with one underscore are reserved in the global scope. This means a macro by the implementation can't (shouldn't) have a name of, say, `_foo`, because it affects more than just the global scope with a name not reserved for use by it. – chris Sep 08 '12 at 20:00
  • I added this class to my git repos. If you want to check it, go to:https://github.com/facunvd/Matrix-Handler... Also I used the Rule of Three. I hope it will useful to you – FacundoGFlores Sep 09 '12 at 17:08

1 Answers1

2

Here's one error

void linearMatrix::Generate_Diagonal_Dominant(void)
{
    for(int i = 0; i < _Width; i++)
        for(int j = 0; j < _Height; j++)
        {
            if(i == j) //Diagonal item
                myVector[i * _Width + j] = 32500;
            else
                myVector[i * _Width + j] = 0.5;
        }
}

should be

void linearMatrix::Generate_Diagonal_Dominant(void)
{
    for(int i = 0; i < _Width; i++)
        for(int j = 0; j < _Height; j++)
        {
            if(i == j) //Diagonal item
                myVector[j * _Width + i] = 32500;
            else
                myVector[j * _Width + i] = 0.5;
        }
}

In other words you have i and j the wrong way round when you calculate the offset (or maybe you should use i * _Height + j). You seem to have made the same mistake throughout.

You have other errors, such as not following the rule of three, as chris mentioned.

john
  • 85,011
  • 4
  • 57
  • 81