Code runs when in main() but gives error when in function

525 views c++
-4

I am writing a dynamic matrix class that stores each non-zero value as a List of 3 elements [row,column,value] I made a dynamic array class called "List", and class"Matrix" a List of list pointers.

My code to transpose the Matrix works:

void transpose(Matrix tripleList)
{
    for (int i = 0; i < tripleList.getNumOfElem(); i++)
    {
        List* list =  new List;
        (*list).copy(*(tripleListMatrix.getAt(i)));
        int temp = (*list).getAt(0);
        (*list).set(0, (*list).getAt(1));
        (*list).set(1, temp);
        (*list).displayList();
        cout << "\n";
    }
}

it works when written directly in main() but gives error when in stand alone function. can anyone explains why and how to fix it?

Full code:

#include <iostream>

using namespace std;

class List  //a dynamic int pointer array
{
private:
    int capacity;
    int numOfElem;
    int *arr;

//initialize all values in capacity to 0
void initialize(int from)
{
    for (int i = from; i < capacity; i++)
    {
        arr[i] = 0;
    }
}

//double the capaicty, then initialize
void expand()
{
    capacity *= 2;
    int *tempArr = new int[capacity];
    for (int i = 0; i < numOfElem; i++)
        tempArr[i] = arr[i];
    delete[] arr;
    arr = tempArr;
    initialize(numOfElem);

}
public:
List()//constructor
{
    capacity = 10;
    numOfElem = 0;
    arr = new int[capacity];
}
~List()//destrcutor
{
    delete[] arr;
}

//add int to the end of List
void append(int newElement)
{
    if (numOfElem >= capacity)
        expand();
    arr[numOfElem++] = newElement;
}

//Copy all element of an  input list to the end of List
void copy(List list)
{
    for (int i = 0; i < list.getNumOfElem(); i++)
    {
        if (numOfElem >= capacity)
            expand();
        arr[numOfElem++] = list.getAt(i);
    }
}

//get reference of the int at an index in te list
int* getAddress(int index)
{
    if (index < 0 || index >= numOfElem)
        throw ("Out of bounds exception!!!");
    return &arr[index];
}

//change the value of at specific index
void set(int index, int value)
{
    arr[index] = value;
}

//get int at an index in te list
int getAt(int index)
{
    if (index < 0 || index >= numOfElem)
        throw ("Out of bounds exception!!!");
    return arr[index];
}


int getNumOfElem()
{
    return numOfElem;
}
void displayList()
{
    for (int i = 0; i < numOfElem; i++)
    {
        cout << arr[i] << " ";
    }
}
};

class Matrix //a List of list pointers
{
private:
int capacity;
int numOfElem;
List* *arr;

void initialize(int from)
{
    for (int i = from; i < capacity; i++)
    {
        arr[i] = new List;
    }
}
void expand()
{
    capacity *= 2;
    List* *tempArr = new List*[capacity];
    for (int i = 0; i < numOfElem; i++)
        tempArr[i] = arr[i];

    delete[] arr;
    arr = tempArr;
    initialize(numOfElem);

}
public:

Matrix()
{
    capacity = 10;
    numOfElem = 0;
    arr = new List*[capacity];
}
~Matrix()
{
    delete[] arr;
}
void append(List* newElement)
{
    if (numOfElem >= capacity)
        expand();
    arr[numOfElem++] = newElement;
}
void set(int index, List* value)
{
    arr[index] = value;
}
List* getAt(int index)
{
    if (index < 0 || index >= numOfElem)
        throw ("Out of bounds exception!!!");
    return arr[index];
}
int getNumOfElem()
{
    return numOfElem;
}
};

void transpose(Matrix tripleList)
{
for (int i = 0; i < tripleList.getNumOfElem(); i++)
{
    {
        List* list =  new List;
        (*list).copy(*(tripleListMatrix.getAt(i)));
        int temp = (*list).getAt(0);
        (*list).set(0, (*list).getAt(1));
        (*list).set(1, temp);
        (*list).displayList();
        cout << "\n";
    }
}
int main()
{
    int m, n, input;
    cout << "Please enter the number of rows and columns of the matrix :\n";
    cin >> m >> n;
    Matrix tripleListMatrix;
    int k = 0;
    cout << "Please enter the matrix : \n";
    for (int i = 0; i < m; i++)
    {
        for (int j = 0; j < n; j++)
        {
            cin >> input;
            if (input != 0)
            {
                tripleListMatrix.append(new List);
                (*(tripleListMatrix.getAt(k))).append(i + 1);
                (*(tripleListMatrix.getAt(k))).append(j + 1);
                (*(tripleListMatrix.getAt(k))).append(input);
                k++;
            }
        }
    }
    cout << "The triple list of matrix is:\n";
    for (int i = 0; i < tripleListMatrix.getNumOfElem(); i++)
    {
        (*(tripleListMatrix.getAt(i))).displayList();
        cout << "\n";
    }
    cout << "\n\n";
//transpose(tripleListMatrix); 
//the code below is the same as in the function transpose but transpose gives error
for (int i = 0; i < tripleListMatrix.getNumOfElem(); i++)
{
    List* list =  new List;
    (*list).copy(*(tripleListMa

answered question

You state that the code gives an error, yet you do not give any information about the error. Do you expect us to debug your program from scratch?

Both your transpose() and Matrix leak like cracy.

Note that in transpose (*list).copy can be written as list->copy, etc., and the code will be much clearer.

1 Answer

2

List* *arr;

When you call transpose(), it makes a copy Matrix because you're not passing by reference. That copy just has a copy of the address for your List, not it's own List object. When the destructor runs on the copy, it clears up the allocated memory, but the original Matrix object in main still points to that same memory. When that object goes away, its destructor tries to free the same memory again and that's bad.

You probably meant:

void transpose(Matrix const & tripleList)

So that no copy is made when calling transpose(), but you should also explicitly delete the copy construtor of Matrix so it cannot be called

Matrix(Matrix const &) = delete;

or make an explicit Matrix copy constructor that makes a deep copy of the memory.

posted this

Have an answer?

JD

Please login first before posting an answer.