Russian Qt Forum
Ноябрь 23, 2024, 08:18 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Добавление в QList по итератору  (Прочитано 5842 раз)
Ostapich
Гость
« : Январь 21, 2019, 12:19 »

Добрый день товарищи!
Столкнулся с проблемой такого рода (код пока не могу предоставить, попытаюсь описать своими словами)
В классе А1 есть список , сигналом я передаю в класс B1 итератор на элемент этого списка и запихиваю его в другой список.
Но почему то программа вылетает. Мои подозрения что при записи в новый список, указатели меняются и элемент на который указывает итератор так же меняется.
Как можно решить проблему?
Мои подозрения: либо использовать Cend (чтобы возвращал константые ссылки), но это спорное решение.
Либо использовать не QList  в классе B1, а например QLinkedList или std::list, как я понимаю они не меняют порядок при добавлении-удалении.
Плз, хелп. Если к вечеру не найдем решения, выложу код.
« Последнее редактирование: Январь 21, 2019, 12:22 от Ostapich » Записан
ssoft
Программист
*****
Offline Offline

Сообщений: 584


Просмотр профиля
« Ответ #1 : Январь 21, 2019, 13:00 »

В классе А1 есть список , сигналом я передаю в класс B1 итератор на элемент этого списка и запихиваю его в другой список.
Но почему то программа вылетает.
...

А может потому что итераторы одного контейнера нельзя запихивать в другой?
Можно запихивать копию значения, доступного по итератору, но не сам итератор.
При этом нужно помнить, что итератор без контейнера не существует.
Контейнер удалили - итератор невалидный. Контейнер изменили - итератор, скорее всего, невалидный.
Так что передавать итераторы через сигнал слот не очень хорошая идея.
Записан
Ostapich
Гость
« Ответ #2 : Январь 21, 2019, 13:12 »

Пробовал я сначала скопировать значение итератора (разыменовав итератор) в отдельное значение, а потом его запихнуть в QList, такая же фигня.
Записан
Ostapich
Гость
« Ответ #3 : Январь 21, 2019, 13:13 »

В классе А1 есть список , сигналом я передаю в класс B1 итератор на элемент этого списка и запихиваю его в другой список.
Но почему то программа вылетает.
...

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

Я запихивал не итератор в контейнер, а то значение на которое он указывает.
Записан
Ostapich
Гость
« Ответ #4 : Январь 21, 2019, 22:57 »

Добрался я до кода. Поменял QList на QLinkedList, не помогло. Пытался делать максимально констатными итераторы, тоже не помогло. Короче ввожу в курс дела, надеюсь кто то поможет.
Проблема такая. У меня приложение, по нажатию кнопки вызывается слот из класса SwitchControl - Passage().В этом слоте, происходит манипуляция с итераторами которая хорошо работает, но как только я сигналом из определенных участков пытаюсь передать значение *pointrPrem (QLinkedList<Premiks>::iterator pointrPrem - хранит итераторы на нужные объекты списка) обратно в MainWindow, вызывается слот void MainWindow::PrintInItog(const Premiks pointrPrem), программа виснет, причем (отладчиком не умею пользоваться) по логу дебага останавливается где то тут (класс SwitchControl ,слот Passage()) :
Код:
        if(pointWeightOne == pointrPrem->compWei.end()){
            emit printComponentOne("");
            qDebug() << "Passage(1^^^^^ ";
        }
        else{
            qDebug() << "Passage(2^^^^^ ";
            emit printComponentOne(pointWeightOne->nameComponent);
        }

Я максимально задебажил, прошу прощения за лапшу и не судите строго, но третий день мучаюсь. Все работало, хотел сделать чтобы в окошке отображались еще дополнительные данные, а тут такая проблема.
Причем когда я коменчу функцию PrintInItog в MainWindow вот до такого состояния, то все работает и в дебаг отображаются корректные данные.
Код:
void MainWindow::PrintInItog(const Premiks pointrPrem){
    //    QList<Premiks> listPrem;
    //    Premiks pointrPremTmp ;
    //    double premiks=0;
    //    double itogRec=0;

//    qDebug() <<"START";
//    if(liistPremiks.isEmpty()){
//        qDebug() <<"TWADawdawd"<< liistPremiks.isEmpty();
//        qDebug() <<"PrintInItog(const Premiks pointrPrem)1111111111111";
//                pointrPremTmp = pointrPrem;
//                liistPremiks << pointrPrem;
//                qDebug() <<"LIST"<<liistPremiks.size();
                qDebug() <<"NAME"<<pointrPrem.itogPrem;
                qDebug() <<"NAME"<<pointrPrem.namePrem;
        //        qDebug() <<"TWADawdawd"<< listPrem.isEmpty();
        //        qDebug() <<"Name Prem"<< pointrPremTmp.namePrem;
//    }
//    else{
//        qDebug() <<"222222222";
//        if(pointrPremTmp != pointrPrem){
//            qDebug() <<"PrintInItog(const Premiks pointrPrem)333333333333";

//            liistPremiks +=pointrPrem;
//            pointrPremTmp = pointrPrem;
//            qDebug() <<"LIST"<<liistPremiks.size();
//        }
//        else {
//            qDebug() <<"PrintInItog(const Premiks pointrPrem)44444444444";
//        }
//        qDebug() <<"PrintInItog(const Premiks pointrPrem)5555555555555";
//        qDebug() <<"Print";
//        Print(liistPremiks);
//    }

}


Лог когда в закоменченном состоянии:



Лог когда раскоменчиваю хотя бы добавление в список значения :

Код:
liistPremiks << pointrPrem;

тут:

 


Заранее  благодарен!

MainWindow h.
Код:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QTimer>
#include <QPixmap>
#include <QLinkedList>

#include "port.h"
#include "recepe.h"
#include "switchcontrol.h"
#include "counterwindow.h"



namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

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

signals:
    void writeData(QByteArray name);//сигнал записи в порт
    void send();
    void eguallySignal(bool tmp);


private:
    Ui::MainWindow *ui;
    bool statusStab = false;
    bool statusEqually = false;
    QLinkedList<Premiks> liistPremiks;
    Premiks pointrPremTmp ;
    double premiks=0;
    double itogRec=0;

private slots:
    void ReadWeight (double weightActual);
    void OnOfCheckBox(bool tmp);
    void disableButton();
    void setWeight(double tmp);
    void Equally(bool tmp);//слот включения выключения иконки равно
    void PrintInItog(const Premiks pointrPrem);
    void Print(QLinkedList<Premiks> &tmp);

private:
    QTimer *pSendTimer;
    QPixmap myPixmapS_on;//Переменная хранящая иконку на ВКЛ стабильного веса
    QPixmap myPixmapS_of;//Переменная хранящая иконку на ВЫКЛ стабильного веса
    QPixmap myPixmapEqually_on;//Переменная хранящая иконку на ВКЛ равно
    QPixmap myPixmapEqually_of;//Переменная хранящая иконку на ВЫКЛ равно
    double weight;//вес текущего компонента
};

#endif // MAINWINDOW_H

MainWindow cpp
Код:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <qdebug.h>
#include <QString>
#include <QThread>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    myPixmapS_on.load("C:\\Qt\\Projects\\build-Libra_ADH_pro-Desktop_Qt_5_9_3_MinGW_32bit-Debug\\debug\\icons\\key_S_on");
    myPixmapS_of.load("C:\\Qt\\Projects\\build-Libra_ADH_pro-Desktop_Qt_5_9_3_MinGW_32bit-Debug\\debug\\icons\\key_S");
    myPixmapEqually_of.load("C:\\Qt\\Projects\\build-Libra_ADH_pro-Desktop_Qt_5_9_3_MinGW_32bit-Debug\\debug\\icons\\key_equal_of");
    myPixmapEqually_on.load("C:\\Qt\\Projects\\build-Libra_ADH_pro-Desktop_Qt_5_9_3_MinGW_32bit-Debug\\debug\\icons\\key_equal_on");
    ui->label_4->setPixmap(myPixmapS_of);
    ui->label_5->setPixmap(myPixmapEqually_of);
    ui->label->setStyleSheet("QLabel { background-color : lightgray; color : black; }");
    //palette.setColor(ui->pLabel->foregroundRole(), Qt::yellow);

    QThread *thread_New = new QThread;//Создаем поток для порта платы
    Port *PortNew = new Port();//Создаем обьект по классу

    PortNew->moveToThread(thread_New);//помешаем класс  в поток
    PortNew->thisPort.moveToThread(thread_New);//Помещаем сам порт в поток
//    connect(PortNew, SIGNAL(error_(QString)), this, SLOT(Print(QString)));//Лог ошибок
    connect(thread_New, SIGNAL(started()), PortNew, SLOT(process_Port()));//Переназначения метода run
    connect(PortNew, SIGNAL(finished_Port()), thread_New, SLOT(quit()));//Переназначение метода выход
    connect(thread_New, SIGNAL(finished()), PortNew, SLOT(deleteLater()));//Удалить к чертям поток
    connect(PortNew, SIGNAL(finished_Port()), thread_New, SLOT(deleteLater()));//Удалить к чертям поток
//    connect(PortNew, SIGNAL(outPort(QString)), this, SLOT(Print(QString)));//Лог ошибок
    connect(this,SIGNAL(writeData(QByteArray)),PortNew,SLOT(WriteToPort(QByteArray)));
    connect(PortNew, SIGNAL(sendWeight(double)),this,SLOT(ReadWeight(double)));
    connect(PortNew,SIGNAL(stability(bool)),this,SLOT(OnOfCheckBox(bool)));
    connect(this,SIGNAL(eguallySignal(bool)),this,SLOT(Equally(bool)));
    connect(this,SIGNAL(send()),PortNew,SLOT(SendStartPack()));
    thread_New->start();


    pSendTimer=new QTimer();
    pSendTimer->setInterval(50);

    connect(pSendTimer, SIGNAL(timeout()),this, SIGNAL(send()));//связь с таймером (каждые 50 мс, отправляем запрос на весы)
    pSendTimer->start(250);
    Recepe recOne("Барбекю 15000321");
    SwitchControl *Control= new SwitchControl(recOne);
    //заполнение списков для рецептуры
    recOne.FillOne();
    connect(Control,SIGNAL(printInNameRecept(QString)),ui->label_2,SLOT(setText(QString)));
    connect(Control,SIGNAL(printNamePremiks(QString)),ui->label_3,SLOT(setText(QString)));
    connect(Control,SIGNAL(printComponentOne(QString)),ui->label_8,SLOT(setText(QString)));
    connect(Control,SIGNAL(printComponentTwo(QString)),ui->label,SLOT(setText(QString)));
    connect(Control,SIGNAL(printComponentThree(QString)),ui->label_7,SLOT(setText(QString)));
    connect(Control,SIGNAL(printWeight(double)),ui->lcdNumber_2,SLOT(display(double)));
    connect(Control,SIGNAL(printWeight(double)),this,SLOT(setWeight(double)));
    connect(ui->pushButton,SIGNAL(clicked(bool)),Control,SLOT(Passage()));
    connect(ui->pushButton,SIGNAL(clicked(bool)),this,SLOT(disableButton()));
    connect(Control,SIGNAL(sendListPremiks(const Premiks)),SLOT(PrintInItog(const Premiks)));
    Control->ArrangePointAndStartDispley(recOne);

    //*******
    ui->pushButton->setEnabled(false);
}

MainWindow::~MainWindow()
{
    delete ui;

    if(pSendTimer)
        delete pSendTimer;
}

void MainWindow::ReadWeight (double weightActual){
    ui->lcdNumber->display(weightActual);
    if(weight == weightActual && statusStab == true){//проверяем на равенство
        ui->pushButton->setEnabled(true);
        emit eguallySignal(true);
    }
    else {
        ui->pushButton->setEnabled(false);
        emit eguallySignal(false);
    }

}

void MainWindow::OnOfCheckBox(bool tmp){//функция смены картинки стабильности
    if(tmp!= statusStab){
        statusStab = !statusStab;
        if(statusStab==true){
            ui->label_4->setPixmap(myPixmapS_on);
        }
        else
            ui->label_4->setPixmap(myPixmapS_of);
    }
}

void MainWindow::Equally(bool tmp){//функция смены картинки равно

    if(tmp != statusEqually){
        statusEqually = !statusEqually;
        if(statusEqually == true){
            ui->label_5->setPixmap(myPixmapEqually_on);
        }
        else {
            ui->label_5->setPixmap(myPixmapEqually_of);
        }
    }

}


void MainWindow::disableButton()//слот оключения кнопки по нажатию на нее.
{
    ui->pushButton->setEnabled(false);
}

void MainWindow::setWeight(double tmp){//вес компонента получаем сигналом
    weight = tmp;
}

void MainWindow::PrintInItog(const Premiks pointrPrem){
    //    QList<Premiks> listPrem;
    //    Premiks pointrPremTmp ;
    //    double premiks=0;
    //    double itogRec=0;

    qDebug() <<"START";
    if(liistPremiks.isEmpty()){
        qDebug() <<"TWADawdawd"<< liistPremiks.isEmpty();
        qDebug() <<"PrintInItog(const Premiks pointrPrem)1111111111111";
                pointrPremTmp = pointrPrem;
                liistPremiks << pointrPrem;
                qDebug() <<"LIST"<<liistPremiks.size();
                qDebug() <<"NAME"<<pointrPrem.itogPrem;
                qDebug() <<"NAME"<<pointrPrem.namePrem;
        //        qDebug() <<"TWADawdawd"<< listPrem.isEmpty();
        //        qDebug() <<"Name Prem"<< pointrPremTmp.namePrem;
    }
    else{
        qDebug() <<"222222222";
        if(pointrPremTmp != pointrPrem){
            qDebug() <<"PrintInItog(const Premiks pointrPrem)333333333333";

            liistPremiks +=pointrPrem;
            pointrPremTmp = pointrPrem;
            qDebug() <<"LIST"<<liistPremiks.size();
        }
        else {
            qDebug() <<"PrintInItog(const Premiks pointrPrem)44444444444";
        }
        qDebug() <<"PrintInItog(const Premiks pointrPrem)5555555555555";
        qDebug() <<"Print";
        Print(liistPremiks);
    }

}

void MainWindow::Print(QLinkedList<Premiks> &tmp){
    qDebug() <<"PrintINNNN";
    foreach (Premiks var, tmp) {
        qDebug() << var.namePrem<< " " << var.itogPrem;
        qDebug() << premiks<< " " ;
    }
}


SWITCHCONTROL_H
Код:
#ifndef SWITCHCONTROL_H
#define SWITCHCONTROL_H

#include <QMainWindow>
#include <QObject>
#include <QWidget>
#include "recepe.h"
#include <QLinkedList>

class SwitchControl : public QObject
{
    Q_OBJECT
public:
    SwitchControl();
    SwitchControl (Recepe tmp) : recContainer (tmp) {}
    SwitchControl& operator= (/*const */SwitchControl &drob);
private:

    Recepe recContainer;
    QList<Weight>::iterator pointWeightOne;//Итератор указывающий на предыдущий компонент
    QList<Weight>::iterator pointWeightTwo;//Итератор указывающий на текущий компонент
    QList<Weight>::iterator pointWeightThree;//Итератор указывающий на следующий компонент
    QLinkedList<Premiks>::iterator pointrPrem;//Итератор указывающий на Премикс
    QLinkedList<Premiks> listPremiks;//полный список всех Премиксов


private slots:
public slots:
    Recepe returnrecContainer();
    QList<Weight>::iterator returnrecpointWeightOne();//   |             *****
    QList<Weight>::iterator returnrecpointWeightTwo();//   | Возвращают закрытые члены класса
    QList<Weight>::iterator returnrecpointWeightThree();// |             *****
     QLinkedList<Premiks>::iterator returnrecpointrPrem();//     |
    void ArrangePointAndStartDispley(Recepe recept);//инициализация рецептурой
    void Passage();//прохождение по нажатию по рецептуре

signals:
    void printInNameRecept(QString name);//сигнал по передаче имени Рецептуры на дисплей в mainwindow
    void printNamePremiks(QString name);//сигнал по передаче имени Премикса
                                          //на дисплей в mainwindow(привязан к итератору pointrPrem
    void printComponentOne(QString name);//сигнал по передаче имени Предыдущего компонента
                                          //на дисплей в mainwindow(привязан к итератору pointWeightOne
    void printComponentTwo(QString name);//сигнал по передаче имени Текущего компонента
                                           //на дисплей в mainwindow(привязан к итератору pointWeightTwo
    void printComponentThree(QString name);//сигнал по передаче имени Следующего компонента
                                            //на дисплей в mainwindow(привязан к итератору pointWeightThree
    void printWeight(double weight);//сигнал по передаче Веса на дисплей в mainwindow

    void sendListPremiks(Premiks pointrPremTmp);
};

#endif // SWITCHCONTROL_H

SWITCHCONTROL_CPP
Код:
#include "switchcontrol.h"



Recepe SwitchControl::returnrecContainer(){
    return recContainer;

}
QList<Weight>::iterator SwitchControl::returnrecpointWeightOne(){
    return  pointWeightOne;
}
QList<Weight>::iterator SwitchControl::returnrecpointWeightTwo(){
    return pointWeightTwo;
}
QList<Weight>::iterator SwitchControl::returnrecpointWeightThree(){
    return pointWeightThree;
}
 QLinkedList<Premiks>::iterator SwitchControl::returnrecpointrPrem(){
    return pointrPrem;
}

SwitchControl& SwitchControl::operator= (/*const */SwitchControl &drob){
    this->recContainer = drob.returnrecContainer();
    this->pointWeightOne = drob.returnrecpointWeightOne();
    this->pointWeightTwo = drob.returnrecpointWeightTwo();
    this->pointWeightThree = drob.returnrecpointWeightThree();
    this->pointrPrem = drob.returnrecpointrPrem();
    return *this;
}

void SwitchControl::ArrangePointAndStartDispley(Recepe recept){
    recContainer = recept;
    emit printInNameRecept(recept.nameRecepe);
    listPremiks += recept.basis;
    listPremiks +=recept.listPrem;
    pointrPrem = listPremiks.begin();
    pointWeightOne=pointrPrem->compWei.end();
    pointWeightTwo = pointrPrem->compWei.begin();
    pointWeightThree = pointWeightTwo+1;
    emit printNamePremiks(pointrPrem->namePrem);
    if(pointWeightOne == pointrPrem->compWei.end())
        emit printComponentOne("");
    emit printComponentTwo(pointWeightTwo->nameComponent);
    emit printComponentThree(pointWeightThree->nameComponent);
    emit printWeight(pointWeightTwo->weight);
    qDebug() << "ArrangePointAndStartDispley(Recepe recept)"<<pointrPrem->namePrem;
    sendListPremiks(*(pointrPrem));
}

void SwitchControl::Passage(){
    if(pointrPrem != listPremiks.end()){
qDebug() << "BBBBBBB1 "<<(pointWeightOne != pointrPrem->compWei.end() && pointWeightThree != pointrPrem->compWei.end());
qDebug() << "BBBBBBB2 "<<((pointWeightOne == pointrPrem->compWei.end()));
qDebug() << "BBBBBBBBB3 "<< (pointWeightThree == pointrPrem->compWei.end());
qDebug() << "AAAAAAAAAAAAA1 "<< (pointWeightOne != pointrPrem->compWei.end());
qDebug() << "AAAAAAAAAAAAA1 "<< (pointWeightThree != pointrPrem->compWei.end());
        if(pointWeightOne != pointrPrem->compWei.end() && pointWeightThree != pointrPrem->compWei.end()){
            pointWeightOne++;
            pointWeightTwo++;
            pointWeightThree++;
            qDebug() << "Passage()111111111111111111 "<<pointrPrem->namePrem;
            emit sendListPremiks(*pointrPrem);
        }
        else if(pointWeightOne == pointrPrem->compWei.end()){
            pointWeightOne = pointWeightTwo;
            pointWeightTwo ++;
            pointWeightThree =  pointWeightTwo + 1;
            qDebug() << "Passage()222222222 "<<pointrPrem->namePrem;
            emit sendListPremiks(*pointrPrem);
        }
        else if(pointWeightThree == pointrPrem->compWei.end()) {
            if(pointrPrem == listPremiks.end()-1){
                pointrPrem = listPremiks.begin();
            }
            else {
                pointrPrem++;
            }
            pointWeightOne=pointrPrem->compWei.end();
            pointWeightTwo = pointrPrem->compWei.begin();
            pointWeightThree = pointWeightTwo+1;
            qDebug() << "Passage()333333333333333 "<<pointrPrem->namePrem;
            emit sendListPremiks(*pointrPrem);
            emit printNamePremiks(pointrPrem->namePrem);
        }
        if(pointWeightOne == pointrPrem->compWei.end()){
            emit printComponentOne("");
            qDebug() << "Passage(1^^^^^ ";
        }
        else{
            qDebug() << "Passage(2^^^^^ ";
            emit printComponentOne(pointWeightOne->nameComponent);
        }
        if(pointWeightThree == pointrPrem->compWei.end()){
            qDebug() << "Passage(3^^^^^ ";
            emit printComponentThree("");
        }
        else{
            qDebug() << "Passage(4^^^^^ ";
            emit printComponentThree(pointWeightThree->nameComponent);
        }
        qDebug() << "Passage(5^^^^^ ";
//        emit sendListPremiks(*(pointrPrem));
        emit printComponentTwo(pointWeightTwo->nameComponent);
        emit printWeight(pointWeightTwo->weight);
    }
            qDebug() << "Passage()4444444444444444 "<<pointrPrem->namePrem;
}

Записан
ViTech
Гипер активный житель
*****
Offline Offline

Сообщений: 858



Просмотр профиля
« Ответ #5 : Январь 22, 2019, 12:52 »

Не стоит хранить итераторы в полях класса (SwitchControl), а также передавать их через сигнал-слот. Как правило, итераторы нужны для кратковременного доступа к элементам контейнера, а не для долговременного хранения "указателя" на элемент в контейнере. После изменения контейнера есть большая вероятность, что итераторы станут невалидными.

QList::iterator
Цитировать
Multiple iterators can be used on the same list. However, be aware that any non-const function call performed on the QList will render all existing iterators undefined. If you need to keep iterators over a long period of time, we recommend that you use QLinkedList rather than QList.

QLinkedList::iterator
Цитировать
Multiple iterators can be used on the same list. If you add items to the list, existing iterators will remain valid. If you remove items from the list, iterators that point to the removed items will become dangling iterators.

Цитировать
Warning: Iterators on implicitly shared containers do not work exactly like STL-iterators. You should avoid copying a container while iterators are active on that container. For more information, read Implicit sharing iterator problem.

Попробуйте переписать программу без хранения и передачи итераторов в сигналах.
Записан

Пока сам не сделаешь...
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #6 : Январь 22, 2019, 15:16 »

Короче ввожу в курс дела, надеюсь кто то поможет.
Ну допустим кто-то хочет помочь (люди здесь хорошие), и что должен делать этот желающий? Выцарапать копи-пастой огрызки Вашего кода, создать с нуля проект, долить нужные хедеры и.т.п.? Как видите, этого не произошло, получили "общий" ответ типа "переделайте без итераторов" - и поделом. В след раз выкладывайте компилябельный проект в zip.

Для любого контейнера четко определено остаются ли итераторы на него валидными или нет при добавлении/удалении. Для QLinkedList или std::list (но не QList) они валидны, стало быть передача итераторов на них в сигнале корректна и работать должна (смущает только с какой легкостью Вы меняете QList на QLinkedList). Насвистели где-то в др месте. Для начала стоит поменять  QLinkedList на std::list, может имплисит шара подгадила. Но скорее всего развал в потоках, т.к. конейнеры НЕ "потокобезопасны", а никаких намеков на защиту от одновременных записи/чтения не наблюдается
Записан
Ostapich
Гость
« Ответ #7 : Январь 22, 2019, 15:19 »

Не стоит хранить итераторы в полях класса (SwitchControl), а также передавать их через сигнал-слот. Как правило, итераторы нужны для кратковременного доступа к элементам контейнера, а не для долговременного хранения "указателя" на элемент в контейнере. После изменения контейнера есть большая вероятность, что итераторы станут невалидными.

QList::iterator
Цитировать
Multiple iterators can be used on the same list. However, be aware that any non-const function call performed on the QList will render all existing iterators undefined. If you need to keep iterators over a long period of time, we recommend that you use QLinkedList rather than QList.

QLinkedList::iterator
Цитировать
Multiple iterators can be used on the same list. If you add items to the list, existing iterators will remain valid. If you remove items from the list, iterators that point to the removed items will become dangling iterators.

Цитировать
Warning: Iterators on implicitly shared containers do not work exactly like STL-iterators. You should avoid copying a container while iterators are active on that container. For more information, read Implicit sharing iterator problem.

Попробуйте переписать программу без хранения и передачи итераторов в сигналах.
Спасибо!
Тогда подскажите как из итератора получить указатель. Просто чтобы поменьше переписывать....если я правильно понял то вот так:
Код:
T & operator[] ( int j ) const
Записан
ViTech
Гипер активный житель
*****
Offline Offline

Сообщений: 858



Просмотр профиля
« Ответ #8 : Январь 22, 2019, 19:43 »

Тогда подскажите как из итератора получить указатель. Просто чтобы поменьше переписывать....если я правильно понял то вот так:
Код:
T & operator[] ( int j ) const
Из итератора не надо получать указатель. Нужно просто обращаться к содержимому итератора.

В классе А1 есть список , сигналом я передаю в класс B1 итератор на элемент этого списка и запихиваю его в другой список.

Передавайте не итератор, а сам элемент (его копию). Если элементов несколько, то формируйте новый список и его передавайте в сигнале. Возможно лучше будет хранить элементы под управлением std::shared_ptr и работать со списками таких shared_ptr.  Выбор варианта зависит от решаемой задачи.
Записан

Пока сам не сделаешь...
Ostapich
Гость
« Ответ #9 : Январь 24, 2019, 15:46 »

Тогда подскажите как из итератора получить указатель. Просто чтобы поменьше переписывать....если я правильно понял то вот так:
Код:
T & operator[] ( int j ) const
Из итератора не надо получать указатель. Нужно просто обращаться к содержимому итератора.

В классе А1 есть список , сигналом я передаю в класс B1 итератор на элемент этого списка и запихиваю его в другой список.

Передавайте не итератор, а сам элемент (его копию). Если элементов несколько, то формируйте новый список и его передавайте в сигнале. Возможно лучше будет хранить элементы под управлением std::shared_ptr и работать со списками таких shared_ptr.  Выбор варианта зависит от решаемой задачи.
Переделал что передается сам обьект, больше ни где итераторы не передаются. А вот в классе сами итераторы хранятся, ничего страшного? Просто пытался на указатели переделать, приложение крашилось, откатил назад и забил пока.
Записан
ViTech
Гипер активный житель
*****
Offline Offline

Сообщений: 858



Просмотр профиля
« Ответ #10 : Январь 24, 2019, 18:46 »

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

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

Пока сам не сделаешь...
lit-uriy
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3880


Просмотр профиля WWW
« Ответ #11 : Февраль 05, 2019, 14:25 »

не все итераторы позволяют модифицировать контейнеры, подробнее тут.
Для Списка есть специальный итератор QMutableListIterator
Записан

Юра.
Ostapich
Гость
« Ответ #12 : Февраль 11, 2019, 00:23 »

Спасибо!
А еще, перенес проект на raspberry , как правильно на Ubuntu пути к библиотекам указывать ? есть разница как это делается на винде и на Linux е?....
Может в pro файле как то по другому? Ничего не понимаю....
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.099 секунд. Запросов: 22.