Qt - 向地图和内存泄漏添加元素

时间:2016-05-04 21:06:55

标签: c++ qt memory memory-leaks

我正在研究矩阵计算器,我遇到了一个非常烦人的问题,现在已经尝试修复它3个小时了,但它变得更糟而不是变得更好。也许你能够提供帮助。

这是我的MainWindow课程:

    #ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QPushButton>
#include <QGridLayout>
#include <QLabel>
#include "addmatrix.h"
#include "memory.h"
#include "matrixcreation.h"
#include <QMap>
#include "matrix.h"


namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(MainWindow *parent = 0);
    ~MainWindow();


private slots:
    void on_createButton_clicked();
    void setMatrix(Matrix *matrix);

private:
    Matrix getMatrixFromMemory(QString &name);
    void addMatrixToMemory();
    Ui::MainWindow *ui;
    AddMatrix *add;
    MatrixCreation *matrixCreate;
    QMap <QString, Matrix> matrixMap;
};

#endif // MAINWINDOW_H

.cpp文件

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(MainWindow *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    this->setWindowTitle("Matrix Calculator");
    add = NULL;
    matrixCreate = NULL;


}

MainWindow::~MainWindow()
{
    delete ui;
    delete add;
    delete matrixCreate;
    matrixMap.clear();

}


void MainWindow::on_createButton_clicked()
{
    if (add != NULL)
    {
        delete add;
        add = new AddMatrix;
    }
    else
        add = new AddMatrix;
    if (matrixCreate != NULL)
    {
        ui->label->setText(getMatrixFromMemory(matrixCreate->getMatrix()->getName()).getName());
        delete matrixCreate;
        matrixCreate = new MatrixCreation;
    }
    else
        matrixCreate = new MatrixCreation;

    // Polaczenie sygnalow ze slotami

    // Sluzy ustawieniu liczby wierszy w matrixCreate
    connect(add->getCombo1(), SIGNAL(currentIndexChanged(QString)), matrixCreate, SLOT(setRows(QString)));

    // Jak wyzej, tylko kolumn
    connect(add->getCombo2(), SIGNAL(currentIndexChanged(QString)), matrixCreate, SLOT(setColumns(QString)));

    // Ustawienie pola name w matrixCreate


       connect(add->getEdit(), SIGNAL(textChanged(QString)), matrixCreate, SLOT(setName(QString)));

        // Po ustawieniu liczby wierszy i kolumn oraz nazwy macierzy - wywola sie slot updateTable
        // ktory sluzy do ustawienia rozmiaru okna i tabeli
        connect(add, SIGNAL(setupSuccessful()), matrixCreate, SLOT(updateTable()));

        // Po ustawieniu wierszy, kolumn, ustawieniu nazwy, rozmiarow, wywola sie slot show matrixCreate
        connect(add, SIGNAL(setupSuccessful()), matrixCreate, SLOT(show()));

        // Sluzy dodaniu macierzy do pamieci (mapy)
        connect(matrixCreate, SIGNAL(matrixReady(Matrix*)), this, SLOT(setMatrix(Matrix*)));

        add->show();
    }

    void MainWindow::setMatrix(Matrix *matrix)
    {
        matrixMap[matrix->getName()] = *matrix;
    }

    Matrix MainWindow::getMatrixFromMemory(QString &name)
    {
        return matrixMap[name];
    }

正如您所看到的,我的MainWindow中有一个QMap。我还有一个名为matrixCreate的MatrixCreation类实例。

这是MatrixCreation类:

    #ifndef MATRIXCREATION_H
#define MATRIXCREATION_H

#include <QDialog>
#include <QTableView>
#include <QPushButton>
#include <QStandardItem>
#include <QTableWidget>
#include <QMainWindow>
#include "matrix.h"
#include "memory.h"
#include "addmatrix.h"
#include <windows.h>




namespace Ui {
class MatrixCreation;
}

class MatrixCreation : public QWidget
{
    Q_OBJECT

public:
    explicit MatrixCreation(QWidget *parent = 0);
    ~MatrixCreation();


    QTableWidget *getTable();
    Matrix *getMatrix();

private slots:
    void on_okButton_clicked();
    void updateTable();
    void setRows(QString rows);
    void setColumns(QString columns);
    void setName(QString name);

signals:
    void matrixReady(Matrix *matrix);

private:
    Ui::MatrixCreation *ui;
    int rows;
    int columns;
    int **matrix;
    QString name;
    Matrix *newMatrix;
};

#endif // MATRIXCREATION_H

.cpp文件

    #include "matrixcreation.h"
#include "ui_matrixcreation.h"


MatrixCreation::MatrixCreation(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::MatrixCreation)
{
    ui->setupUi(this);
    this->resize(150, 50);

    // Ustawienie rozmiaru wysokosci wiersza na 40 piksele
    ui->tableWidget->verticalHeader()->setDefaultSectionSize(40);

    // Ustawienie rozmiaru szerokosci kolumny na 94 piksele
    ui->tableWidget->horizontalHeader()->setDefaultSectionSize(94);

    // Dopasowanie rozmiaru kolumn do rozmiaru tabeli
    ui->tableWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
    ui->tableWidget->verticalHeader()->setSectionResizeMode(QHeaderView::Stretch);

    // Wylaczenie scrollbarow tabeli
    ui->tableWidget->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    ui->tableWidget->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);

    rows = 1;
    columns = 1;
    matrix = NULL;
    newMatrix = new Matrix;

}

MatrixCreation::~MatrixCreation()
{
    delete ui;
    if (matrix != NULL)
    {
        for (int i = 0; i < rows; i++)
            delete matrix[i];
    }
    delete newMatrix;
}

void MatrixCreation::setRows(QString rows)
{
    this->rows = rows.toInt();
}

void MatrixCreation::setColumns(QString columns)
{
    this->columns = columns.toInt();
}

// Metoda odpowiedzialna za utworzenie odpowiedniej ilosci wierszy i kolumn
// oraz ustawienie odpowiedniej wielkosci okna i rozmiaru tabeli
void MatrixCreation::updateTable()
{
    // stale roznice miedzy szerokoscia i wysokoscia okna i tabeli
    int w = 323 - 305;
    int h = 300 - 227 + 15;

    for(int i = 0; i < rows; i++)
    {
        ui->tableWidget->insertRow(i);
        h += 35;
    }
    for(int j = 0; j < columns; j++)
    {
        ui->tableWidget->insertColumn(j);
        w += 50;
    }
    this->resize(w, h);
    this->setMinimumSize(w, h);

    ui->retranslateUi(this);
    this->setWindowTitle("Matrix Creation");
}

QTableWidget *MatrixCreation::getTable()
{
    return ui->tableWidget;
}

void MatrixCreation::on_okButton_clicked()
{
    matrix = new int *[rows];
    for(int j = 0; j < rows; j++)
    {
        matrix[j] = new int[columns];
    }

    for(int i = 0; i<rows; i++)
    {
        for(int j = 0; j<columns; j++)
        {
            matrix[i][j] = ui->tableWidget->item(i, j)->text().toInt();
        }
    }


    // Ustawienie pol skladowych w zmiennej newMatrix klasy Matrix
    newMatrix->setColumns(columns);
    newMatrix->setRows(rows);
    newMatrix->setName(name);
    newMatrix->setMatrix(matrix);

    emit matrixReady(newMatrix);



    this->close();
}

void MatrixCreation::setName(QString name)
{
    this->name = name;
}



Matrix *MatrixCreation::getMatrix()
{
    return newMatrix;
}

问题是什么: 我想通过发出这个信号将创建的矩阵添加到QMap: 发出matrixReady(newMatrix);

Matrix类用于保存矩阵的所有元素(行,列,单元格和名称的值)。 但是,Matrix对象未添加到QMap。但是,当我在MatrixCreation析构函数中删除此行时: 删除newMatrix; 有用。

第二个问题: 当我关闭我的应用程序并调用MainWindow析构函数时,在销毁地图时会显示错误:BLOC_TYPE_IS_VALID bla bla ... 我不知道如何解决它,但我会继续努力。任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:0)

void MainWindow::setMatrix(Matrix *matrix)
{
    matrixMap[matrix->getName()] = *matrix;
}

您正在将矩阵的副本添加到地图中。所以这里有泄漏。

void MainWindow::setMatrix(Matrix *matrix)
{
    matrixMap[matrix->getName()] = *matrix;
    delete matrix;
}

这可以解决您的问题。

使用valgrind分析您的应用程序并查找内存泄漏:http://valgrind.org/docs/manual/quick-start.html