1

I'm relatively new at c++ and other object oriented languages as a whole (have done one semester of C classes and now I'm having c++ classes). I'm having problems concerning the making of a dynamically allocated two-dimensional array through a class with a classmate.

The exercise itself would be:

Prepare a class named "matrix" capable of storing two-dimensional arrays dynamically allocated (for float variables). Remember that information such as height and width have to be properly stored somewhere, element pointers too.

The class needs to contain constructors that allow the creation of objects using one of the following strategies: The creation of an array consisting of MxN elements, example:

Array A (4, 5);

The creation of an empty array:

Array B;
 The creation of an array that is a copy of another previous one:

Array C (A);  

After some time trying to figure out why it wasn't working properly, our code is currently this: obs: "Matriz" is how we call a two-dimensional array in our language.

Matriz.h

#pragma once
class Matriz{
    public:
        int l, c;
        float** matriz;
        void setL(int _l);
        void setC(int _c);
        int getL();
        int getC();
        Matriz();
        Matriz(int _l, int _c);
        Matriz(Matriz& m);
        float **getMatriz();
        float getElement(int pL, int pC);
        void setElement(int pL, int pC, float value);
    };

Matriz.cpp

 #include "Matriz.h"

Matriz::Matriz(){
    l = c = 0;
    matriz = new float*[l];

    for (int i = 0; i<l; i++) {
        matriz[l] = new float[c];
    }
}

Matriz::Matriz(Matriz& m){
    l = m.getL();
    c = m.getC();
    matriz = new float*[l];

    for (int i = 0; i<l; i++) {
        matriz[l] = new float[c];
    }

    for (int i = 0; i<l; i++) {
        for (int j = 0; j<l; j++) {
            matriz[i][j] = m.matriz[i][j];
        }
    }

}

Matriz::Matriz(int _l, int _c){
    l = _l;
    c = _c;

    matriz = new float*[l];

    for (int i = 0; i<l; i++) {
        matriz[l] = new float[c];
    }
}

float **Matriz::getMatriz(){
    return matriz;
}

int Matriz::getC(){
    return c;
}

int Matriz::getL(){
    return l;
}

void Matriz::setC(int _c){
    c = _c;
}
void Matriz::setL(int _l){
    l = _l;
}

float Matriz::getElement(int pL, int pC){
    return matriz[pL][pC];
}

void Matriz::setElement(int pL, int pC, float value){
    matriz[pL][pC] = value;
}

main.cpp

#include "stdafx.h"


int _tmain(int argc, _TCHAR* argv[])
{
    int l = 2, c = 2;
    float **m;
    m = new float*[l];

    for (int i=0; i<2; i++) {
    m[i] = new float[c];
    }

    Matriz a(2, 2);
    a.setC(2);
    a.setL(2);

    cout << " c = " << a.getC() << " l= " << a.getL() << "\n";

    for (int i = 0; i<l; i++) {
        for (int j = 0; j<c; j++) {
            a.setElement(i, j, 0);
            cout << " Elemento " << 1 << " " << 1 << " = " << a.getElement(l, c) << "\n";
        }
    }

    a.setElement(0, 0, 1); // <- this is just for testing



    system("pause");
}

iostream and the class header are both included at stdafx.h

Compiling it at MSVS 2013 breaks at

void Matriz::setElement(int pL, int pC, float value){
    matriz[pL][pC] = value;
}

And we're not really sure why, the debugger is giving me "Unhandled exception at 0x01092E27 in ConsoleApplication15.exe: 0xC0000005: Access violation writing location 0xCDCDCDD1."

We suspect however that something with the array is wrong, and when the program tries to write something into an element of it, it simply doesn't exist/can't be reached, making it impossible to change the value of that specific element.

We're thankful for any help or advice, fell free to suggest improvements or coding advices, learning new things is always good =).

  • 1
    The for loop in your Matriz constructor is referencing matriz[l] when I think it should be referencing matriz[i] – twsaef Apr 21 '15 at 01:23
  • 2
    Assignment operator? Destructor? Where are they? In addition, what are those initial lines in `main()` supposed to accomplish? You allocate memory, then...you do nothing with it. Allocating memory means you're responsible for correctly deallocating it, oherwise you have memory leaks. – PaulMcKenzie Apr 21 '15 at 01:25
  • 1
    `setC` and `setL` are not implemented properly; if they change the size then you will need to change the amount of allocated memroy. – M.M Apr 21 '15 at 01:28
  • Why not simply use a `std::vector>`or something similar? – πάντα ῥεῖ Apr 21 '15 at 01:32
  • I'm currently trying to contact my colleague responsible for this part of the code PaulMcKenzie, I'll edit this as soon as I can get him to answer. As far as I can tell, he mentioned that the program was breaking before he added it at the beginning of main, but I think the problem was somewhere else and he thought this was the "fix" by coincidence. I'll start with the destructor as soon as I get this to work, thanks very much for the input!! =) – João Vitor Chrisóstomo Apr 21 '15 at 01:38

1 Answers1

3

I think your error is actually here: a.getElement(l, c). l and c are the bounds for the array, e.g. 2, when your largest index should only ever be 1.

The other serious flaw (pointed out by twsaef) is your constructor:

for (int i = 0; i<l; i++) {
    matriz[l] = new float[c];
}

Should be

for (int i = 0; i<l; i++) {
    matriz[i] = new float[c];
}

While I'm at it, this is redundant:

Matriz a(2, 2);
a.setC(2);
a.setL(2);

Because the constructor for Matriz will set l and c for you.

Also, what are you planning on doing with this:

float **m;
m = new float*[l];

for (int i=0; i<2; i++) {
m[i] = new float[c];
}

Currently it's not used for anything.

Then, as PaulMcKenzie pointed out, what will happen to your dynamically allocated memory when a Matriz instance goes out of scope?

As Matt McNabb pointed out, what if you need to resize a Matriz instance when setC() or setL() are called? At the moment, they only set the member variable and do nothing with the memory.

Community
  • 1
  • 1
AndyG
  • 39,700
  • 8
  • 109
  • 143
  • Hi AndyG, thank you very much for your input!!! We did not realize the first for was set as "matriz[l] = new float[c];", copy pasting it numerous time put the same error all across the code. After doing the fixes mentioned here, it's apparently working if we don't try to change C or L, we'll work on it now. Best regards! – João Vitor Chrisóstomo Apr 21 '15 at 02:00