代码在main()中运行,但在函数中给出错误

时间:2018-11-05 02:34:31

标签: c++ function parameter-passing c++14

我正在编写一个动态矩阵类,该类将每个非零值存储为3个元素的列表[行,列,值] 我制作了一个动态数组类,叫做“列表”,而“矩阵”类是一个列表指针的列表。

我的转置Matrix的代码有效:

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";
    }
}

直接在main()中编写时可以工作,但在独立函数中会出错。谁能解释为什么以及如何解决?

完整代码:

#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(*(tripleListMatrix.getAt(i)));
    int temp = (*list).getAt(0);
    (*list).set(0, (*list).getAt(1));
    (*list).set(1, temp);
    (*list).displayList();
    //cout << "\t" << list;
    cout << "\n";
}
cout << "\n\n";

//checking that tripleListMatrix is unchanged
for (int i = 0; i < tripleListMatrix.getNumOfElem(); i++)
{
    (*(tripleListMatrix.getAt(i))).displayList();
    cout << "\n";
}

return 0;
}

1 个答案:

答案 0 :(得分:1)

  

列表* * arr;

调用transpose()时,它会复制Matrix,因为您没有通过引用传递。该副本仅具有列表的地址副本,而不是其自己的List对象。当析构函数在副本上运行时,它将清除分配的内存,但是main中的原始Matrix对象仍指向该相同的内存。当该对象消失时,其析构函数将尝试再次释放相同的内存,这很糟糕。

您可能是说:

void transpose(Matrix const & tripleList)

这样,在调用transpose()时不会产生任何副本,但是您也应该显式删除Matrix的副本构造函数,以便不能对其进行调用

Matrix(Matrix const &) = delete;

或创建一个显式的Matrix复制构造函数,以构造内存的深层副本。