В чем проблема при очистки памяти?

У меня было задание по написанию программы которая при вводе числа в поле и при нажатии на кнопку добавляет лейбл с числом которые было введено в поле в layout. Я это реализовал через динамическую память и массивы(такое было задание, без всяких векторов и подобных вещей) вот код:

mainwindow.h:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QPushButton>
#include <QLabel>
#include <QPushButton>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
    int NumberOfOrders = 0;
    int theNumber;
    QLabel *OrderList;
    QLabel *SyncArr;



private slots:
    void on_SumbitNumber_clicked();

private:
    Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H

mainwindow.cpp:

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

}

MainWindow::~MainWindow()
{
    delete ui;

    delete [] OrderList;
    delete OrderList;

    delete [] SyncArr;
    delete SyncArr;
}



void MainWindow::on_SumbitNumber_clicked()
{


    if (NumberOfOrders > 0) {
    delete [] OrderList;
    }

    NumberOfOrders+=1;
    OrderList = new QLabel[NumberOfOrders];

    for (int i = 0; i < NumberOfOrders-1;i++) {
        OrderList[i].setNum(SyncArr[i].text().toInt());
    }
    if (NumberOfOrders > 1) {
    delete [] SyncArr;
    }
    SyncArr = new QLabel[NumberOfOrders];

    theNumber = ui->OrderNumberInput->toPlainText().toInt();
    OrderList[NumberOfOrders-1].setNum(theNumber);
    for (int i = 0; i < NumberOfOrders; i++) {
    ui->OrdersScreen->addWidget(&OrderList[i]);
    }
    for (int i = 0; i < NumberOfOrders;i++) {
        SyncArr[i].setNum(OrderList[i].text().toInt());
    }
    if (NumberOfOrders>4) {
        for (int i = 0; i < NumberOfOrders; i++) {
            qDebug() <<OrderList[i].text().toInt();
        }
    }
}

//orderscreen - layout для добавление, OrderNumberInput - поле для ввода числа

Все работает прекрасно но я заметил в предыдущих программах что если ты работаешь с динамической памятью и массивами и если я где то ее или что то забываю очистить или удалить то после программы возникает ошибка в маке. Так вот после этой программы ошибка тоже возникает и я не понимаю почему. Пожалуйста не надо давать способы решить это задачу по другому или через вектора или что то другое, мне нужно решить именно так и я решил и остается только исправить ошибку с очищением памяти. Помогите пожалуйста что я пропустил и где что не удалил?


Ответы (2 шт):

Автор решения: KoVadim

Не хватает кучи кода, но ошибки и так видны. Операторы new/new[] должны быть с парными delete/delete[].

Смотрим на OrderList. К сожалению, его объявления нет, но его можно догадаться. Удаляете Вы его сразу двумя способами (видимо для надежности:) ). А нужно явно только одним. Создавался через new[], значит удалять нужно только так - delete[] OrderList;.

С SyncArr такая же история.

Также нужно помнить, что delete с точки зрения пользователя "не знает", вызывалось ли для переменной delete. Поэтому, если вызвать два раза подряд для переменной, которая не nullptr, вот где то так

SyncArr = new QLabel[NumberOfOrders];
delete [] SyncArr;
delete SyncArr;

Вы гарантированно получите проблему. Она может не сразу проявится, но бывает всякое - так как тут двойное UB - двойное освобождение ещё и неправильным (непарным) delete.

→ Ссылка
Автор решения: Lofectr

Почитайте про очистку памяти в Qt.

Если коротко: Qt сам очищает память. Вот есть главный класс MainWindow который находится в статик. памяти и он сам удаляется по принципу С++. А его "дети" которые находится в динам. памяти сами удаляются.

Советую прочитать так как подробности я не описывал.

→ Ссылка