Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. App Crash C++ Runtime Library

App Crash C++ Runtime Library

Scheduled Pinned Locked Moved Solved General and Desktop
8 Posts 3 Posters 2.2k Views 2 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • O Offline
    O Offline
    onimusha
    wrote on last edited by
    #1

    I'm running this small app to read some sensors throughout an Arduino board, the problem is if i move too much the window around and play with it i get a C++ Runtime Library crash either using common Qt widgets or Qwt widgets as follows:
    Microsoft Visual C++ Runtime Library
    This application has requested the runtime to terminate it in a unsual way.
    Please contact the application's support team for more information.

    Plus it gets a little bit laggy when i open the port and start reading from the board, Why is that?
    This are my files:
    .pro

    QT       += core gui serialport
    
    greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
    
    TARGET = EMS-ver2TEST
    TEMPLATE = app
    
    
    SOURCES += \
        main.cpp \
        puertoserie2.cpp \
        widget.cpp
    
    HEADERS  += \
        puertoserie2.h \
        widget.h
    
    QMAKE_CXXFLAGS += -std=gnu++14
    

    Headers:
    puertoserie2.h

    #ifndef PUERTOSERIE2_H
    #define PUERTOSERIE2_H
    
    #include <QObject>
    #include <QWidget>
    #include <QSerialPort>
    #include <QByteArray>
    #include <QVector>
    #include <QPushButton>
    
    class PuertoSerie2 : public QWidget{
      Q_OBJECT
    
    public:
      explicit PuertoSerie2(QWidget *parent = nullptr);
    
    private Q_SLOTS:
      // Conecta con el dispositivo transmisor
      void conexion();
    
      // Lleva a cabo una lectura del vector de informacion entrante
      void leerPlaca();
    
    Q_SIGNALS:
      void SENSOR_A(int);
      void SENSOR_B(int);
      void SENSOR_C(int);
      void SENSOR_D(int);
    
    private:
      void emiteValor();
    
      char banderaEstado(QByteRef);
    
      void estado(char, char);
    
      void setValorSensores();
    
      int refactorizar(QByteArray);
    
      // Estado del boton
      int mPuertoEstado;
    
      // Numero del sensor a leer o modificar
      int mComa;
    
      QSerialPort *mPlaca;
    
      // Informacion de los sensores en arreglos para un  manejo mas compacto
      QVector<QByteArray> mSensorList;
      QVector <int> mSensorValor;
    
      // Buffer de entrada
      QByteArray mBuffer;
    
      // Puerto de la PC
      QString mPuerto;
    
      // Boton que establece la conexion
      QPushButton *mBoton;  
    };
    
    #endif // PUERTOSERIE2_H
    
    

    widget.h

    #ifndef WIDGET_H
    #define WIDGET_H
    
    #include <QWidget>
    #include <QDial>
    
    class Widget : public QWidget{
        Q_OBJECT
    public:
        Widget(QWidget *parent = 0);
        ~Widget();
    private:
        QWidget *crearDial(QDial *);
    };
    
    #endif // WIDGET_H
    
    

    Sources:
    puertoserie2.cpp

    #include "puertoserie2.h"
    #include <QMessageBox>
    #include <QBoxLayout>
    #include <QDebug>
    
    PuertoSerie2::PuertoSerie2(QWidget *parent) : QWidget(parent){
      mComa = 0;
      mPuertoEstado = 0;
      mPuerto = "COM3";
      mBuffer = "";
      mSensorList.push_back(QByteArray());
      qDebug() << "Vector de QByteArray" << mSensorList.at(0);
      mSensorValor.push_back(0);
      qDebug() << "Vector de double" << mSensorValor.at(0);
    
      mBoton = new QPushButton("Abrir Puerto", this);
    
      QHBoxLayout *layout = new QHBoxLayout(this);
      layout->addWidget(mBoton);
      layout->addStretch();
    
      connect(mBoton, SIGNAL(clicked()), this, SLOT(conexion()));
     }
    
    char PuertoSerie2::banderaEstado(QByteRef buffer){
      // 'a' = 42 (asterisco, inicio de cadena)
      // 'b' = 44 (coma, separador)
      // 'c' >= 48 (informacion, contenido)
    
      int var = (int)buffer;
    
      if(var == 42){
        return 'a';
      } else if(var == 44){
        return 'b';
      } else if(var >= 48){
        return 'c';
      }
    
      return 'd';
    }
    
    void PuertoSerie2::estado(char bandera, char byte){
      switch (bandera) {
        // El estado a se supone que limpia los valores enteriores del vector
        // para introducir las nuevas lecturas
        case 'a':
          qDebug() << "\n----------Caso 'a' disparado: " << byte;
          qDebug() << "\nTam de los vectores: " << mSensorList.size() <<
                      "| " << mSensorValor.size();
          qDebug() << "\nTam de coma: " << mComa;
    
          for(int i = 0; i < mSensorValor.size(); ++i){
            mSensorValor[i] = 0.0;
          }
          for(int i = 0; i < mSensorList.size(); ++i){
            mSensorList[i].clear();
          }
    
          mComa = 0;
        break;
    
        // El estado es un separador, aumenta el lugar del vector
        case 'b':
         qDebug() << "\n----------Caso 'b' disparado: " << byte;
         qDebug() << "\nTam de los vectores: " << mSensorList.size() <<
                     "| " << mSensorValor.size();
         qDebug() << "\nTam de coma: " << mComa;
         emiteValor();
         mSensorValor.push_back(0);
         mSensorList.push_back(QByteArray());
         ++mComa;
         qDebug() << "\nAcciones llevadas a cabo";
         qDebug() << "\nTam de los vectores: " << mSensorList.size() <<
                     "| " << mSensorValor.size();
         qDebug() << "\nTam de coma: " << mComa;
        break;
    
        // Tenemos informacion y la signamos al posicion actual de la coma
        case 'c':
         qDebug() << "\n----------Caso 'c' disparado: " << byte;
         qDebug() << "Coma actual: " << mComa;
         qDebug() << "\nTam de los vectores: " << mSensorList.size() <<
                     "| " << mSensorValor.size();
         mSensorList[mComa] += byte;
        break;
    
        default:
         qDebug() << "\n%%%%%%%%%%Final de la Cadena";
         qDebug() << "\nTam de los vectores: " << mSensorList.size() <<
                     "| " << mSensorValor.size();
         emiteValor();
         mBuffer.clear();
    
         while(mSensorList.size() > 1){
             mSensorList.pop_back();
         }
    
         while(mSensorValor.size() > 1){
             mSensorValor.pop_back();
         }
        break;
        }
    }
    
    void PuertoSerie2::conexion(){
      if (mPuertoEstado == 0){
    
        mPlaca = new QSerialPort(this);
        mPlaca->setPortName(mPuerto);
        mPlaca->open(QIODevice::ReadWrite);
    
        if(mPlaca->isOpen() == false){
    
    	 QMessageBox::information(this, "Estado",
    	 "Error al Abrir el puerto: " + mPuerto);
    
        } else {
    
    	 mPlaca->setBaudRate(QSerialPort::Baud9600);
    	 mPlaca->setStopBits(QSerialPort::OneStop);
    	 mPlaca->setParity(QSerialPort::NoParity);
    	 mPlaca->setDataBits(QSerialPort::Data8);
    	 mPlaca->setFlowControl(QSerialPort::NoFlowControl);
    
    	 connect(mPlaca, SIGNAL(readyRead()), this, SLOT(leerPlaca()));
    
    	 mBoton->setText("Cerrar Puerto");
    	 QMessageBox::information(this, "Estado",
    	 "Puerto: " + mPuerto + " Abierto");
    	 mPuertoEstado = 1;
    
        }
      } else if (mPuertoEstado == 1){
    
        mPlaca->close();
        mPlaca->destroyed();
        mPuertoEstado = 0;
        mBoton->setText("Abrir Puerto");
        QMessageBox::information(this, "Estado",
        "Puerto: " + mPuerto + " Cerrado");
    
      }
    }
    
    void PuertoSerie2::leerPlaca(){
    
      mBuffer = mPlaca->readAll();
    
      qDebug() << "\n>>>>>>>> Informacion de entrada: " << mBuffer;
    
      for(int i = 0; i < mBuffer.size(); ++i){
        estado(banderaEstado(mBuffer[i]), mBuffer.at(i));
      }
    }
    
    int PuertoSerie2::refactorizar(QByteArray byte){
      // Convierte el valor de binario a un doble usable
    //  qDebug() << "\nRefactorizando: " << byte;
    
      QString cadena = byte;
      int i = cadena.toInt();
    //  qDebug() << "\nRefactorizado: " << i;
      return i;
    
    }
    
    void PuertoSerie2::setValorSensores(){
      qDebug() << "\nSeteando Valores...";
      for(int i = 0; i < mSensorValor.size(); ++i){
        mSensorValor[i] = refactorizar(mSensorList.at(i));
      }
    }
    
    void PuertoSerie2::emiteValor(){
        setValorSensores();
    
        qDebug() <<"\nValores: " << mSensorValor.at(mComa);
        switch(mComa){
    
        case 0:
            emit SENSOR_A(mSensorValor.at(mComa));
        break;
    
        case 1:
            emit SENSOR_B(mSensorValor.at(mComa));
        break;
    
        case 2:
            emit SENSOR_C(mSensorValor.at(mComa));
        break;
    
        case 3:
            emit SENSOR_D(mSensorValor.at(mComa));
        break;
        }
    
    }
    

    widget.cpp

    #include "widget.h"
    #include "puertoserie2.h"
    #include <QDial>
    #include <QBoxLayout>
    #include <QLabel>
    #include <QFont>
    
    Widget::Widget(QWidget *parent) : QWidget(parent){
        PuertoSerie2 *port = new PuertoSerie2;
    
        QDial *dial = new QDial;
        connect(port, SIGNAL(SENSOR_A(int)), dial, SLOT(setValue(int)));
        QWidget *dialWidget = crearDial(dial);
    
        QDial *dialA = new QDial;
        connect(port, SIGNAL(SENSOR_B(int)), dialA, SLOT(setValue(int)));
        QWidget *dialAWidget = crearDial(dialA);
    
        QDial *dialB = new QDial;
        connect(port, SIGNAL(SENSOR_C(int)), dialB, SLOT(setValue(int)));
        QWidget *dialBWidget = crearDial(dialB);
    
        QDial *dialC = new QDial;
        connect(port, SIGNAL(SENSOR_D(int)), dialC, SLOT(setValue(int)));
        QWidget *dialCWidget = crearDial(dialC);
    
        QHBoxLayout *mainLayout = new QHBoxLayout(this);
        mainLayout->addWidget(dialWidget);
        mainLayout->addWidget(dialAWidget);
        mainLayout->addWidget(dialBWidget);
        mainLayout->addWidget(dialCWidget);
        mainLayout->addWidget(port);
    
        this->setLayout(mainLayout);
    }
    
    Widget::~Widget(){
    
    }
    
    QWidget *Widget::crearDial(QDial* dial){
        int min = 0;
        int max = 100;
    
        dial->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
        dial->setMinimum(min);
        dial->setMaximum(max);
    
        QFont font;
        font.setBold(true);
    
        QLabel *label = new QLabel;
        label->setAlignment(Qt::AlignHCenter);
        label->setFont(font);
    
        connect(dial, SIGNAL(valueChanged(int)), label, SLOT(setNum(int)));
        label->setNum(dial->value());
    
        QVBoxLayout *dialLayout = new QVBoxLayout;
        dialLayout->addWidget(dial);
        dialLayout->addWidget(label);
    
        QWidget *box = new QWidget;
        box->setLayout(dialLayout);
        return box;
    }
    
    

    main.cpp

    #include "widget.h"
    #include <QApplication>
    
    int main(int argc, char *argv[]){
        QApplication a(argc, argv);
        Widget w;
        w.show();
    
        return a.exec();
    }
    

    Resistance Is Futile. Your biological and technological distinctiveness will be added to our own.

    1 Reply Last reply
    0
    • Paul ColbyP Offline
      Paul ColbyP Offline
      Paul Colby
      wrote on last edited by
      #2

      Hi @onimusha,

      There's a few suspicious things that could be causing your problems. Let's start with a couple of the ones that stand out to me.

      It seems that PuertoSerie2::leerPlaca is not checking the validity of the PuertoSerie2::mPlaca member before dereferencing it. I can see that your code logic would normally never expect it to be called without being initialised first, but as its connected to a signal, you can't guarantee the order of the events that destroy and use mPlaca (a quick validity check is always advisable anyway).

      Also, the way PuertoSerie2::conexion destroys mPlaca looks risky to me... specifically, the mPlaca->destroyed(); call is (probably) bad - QObject::destroyed is a signal, and probably should not be called this way (at best, it will be ignored, at worst, it will put the object in a very unintended state).

      A better approach might be something like:

      void PuertoSerie2::conexion(){
          ...
          mPlaca->close();
          mPlaca->deleteLater();
          mPlaca = nullptr;
          ...
      }
      

      Then in PuertoSerie2::leerPlaca, check if mPlace is null or not (and/or disconnect the slot prior to the deleteLater call above). As the code stands currently, leerPlace could be calling readAll on a QSerialPort object on which you have invoked QObject::destroyed (which may well have corrupted the object).

      So try fixing up the management of your PuertoSerie2::mPlace pointer's lifecycle, and see if that helps.

      Cheers.

      O 2 Replies Last reply
      0
      • Paul ColbyP Paul Colby

        Hi @onimusha,

        There's a few suspicious things that could be causing your problems. Let's start with a couple of the ones that stand out to me.

        It seems that PuertoSerie2::leerPlaca is not checking the validity of the PuertoSerie2::mPlaca member before dereferencing it. I can see that your code logic would normally never expect it to be called without being initialised first, but as its connected to a signal, you can't guarantee the order of the events that destroy and use mPlaca (a quick validity check is always advisable anyway).

        Also, the way PuertoSerie2::conexion destroys mPlaca looks risky to me... specifically, the mPlaca->destroyed(); call is (probably) bad - QObject::destroyed is a signal, and probably should not be called this way (at best, it will be ignored, at worst, it will put the object in a very unintended state).

        A better approach might be something like:

        void PuertoSerie2::conexion(){
            ...
            mPlaca->close();
            mPlaca->deleteLater();
            mPlaca = nullptr;
            ...
        }
        

        Then in PuertoSerie2::leerPlaca, check if mPlace is null or not (and/or disconnect the slot prior to the deleteLater call above). As the code stands currently, leerPlace could be calling readAll on a QSerialPort object on which you have invoked QObject::destroyed (which may well have corrupted the object).

        So try fixing up the management of your PuertoSerie2::mPlace pointer's lifecycle, and see if that helps.

        Cheers.

        O Offline
        O Offline
        onimusha
        wrote on last edited by onimusha
        #3

        Hi @Paul-Colby,
        Changing a few lines:

        else if (mPuertoEstado == 1){
        
            mPlaca->close();
            mPlaca->deleteLater();
            mPlaca = nullptr;
            mPuertoEstado = 0;
            mBoton->setText("Abrir Puerto");
            QMessageBox::information(this, "Estado",
            "Puerto: " + mPuerto + " Cerrado");
        
          }
        

        and:

        if(mPlaca != nullptr){
        
            mBuffer = mPlaca->readAll();
        
            qDebug() << "\n>>>>>>>> Informacion de entrada: " << mBuffer;
        
            for(int i = 0; i < mBuffer.size(); ++i){
              estado(banderaEstado(mBuffer[i]), mBuffer.at(i));
            }
          }
        

        as you said makes thinks even worse. the whole thing crashes in 2 sec, i cannot think how to manage that king of menber life cicle because this reaches my level of understanding about C++ / Qt / System platform

        Resistance Is Futile. Your biological and technological distinctiveness will be added to our own.

        1 Reply Last reply
        0
        • Paul ColbyP Paul Colby

          Hi @onimusha,

          There's a few suspicious things that could be causing your problems. Let's start with a couple of the ones that stand out to me.

          It seems that PuertoSerie2::leerPlaca is not checking the validity of the PuertoSerie2::mPlaca member before dereferencing it. I can see that your code logic would normally never expect it to be called without being initialised first, but as its connected to a signal, you can't guarantee the order of the events that destroy and use mPlaca (a quick validity check is always advisable anyway).

          Also, the way PuertoSerie2::conexion destroys mPlaca looks risky to me... specifically, the mPlaca->destroyed(); call is (probably) bad - QObject::destroyed is a signal, and probably should not be called this way (at best, it will be ignored, at worst, it will put the object in a very unintended state).

          A better approach might be something like:

          void PuertoSerie2::conexion(){
              ...
              mPlaca->close();
              mPlaca->deleteLater();
              mPlaca = nullptr;
              ...
          }
          

          Then in PuertoSerie2::leerPlaca, check if mPlace is null or not (and/or disconnect the slot prior to the deleteLater call above). As the code stands currently, leerPlace could be calling readAll on a QSerialPort object on which you have invoked QObject::destroyed (which may well have corrupted the object).

          So try fixing up the management of your PuertoSerie2::mPlace pointer's lifecycle, and see if that helps.

          Cheers.

          O Offline
          O Offline
          onimusha
          wrote on last edited by onimusha
          #4

          @Paul-Colby
          One thing to notice is that the same code runs smoother on my IBM thinkpad Z60t under Lubuntu 14.04. Just wonder why....

          Resistance Is Futile. Your biological and technological distinctiveness will be added to our own.

          1 Reply Last reply
          0
          • jsulmJ Offline
            jsulmJ Offline
            jsulm
            Lifetime Qt Champion
            wrote on last edited by
            #5

            You should run a debug build through the debugger to see where it crashes

            https://forum.qt.io/topic/113070/qt-code-of-conduct

            O 2 Replies Last reply
            1
            • jsulmJ jsulm

              You should run a debug build through the debugger to see where it crashes

              O Offline
              O Offline
              onimusha
              wrote on last edited by
              #6

              Hello @jsulm i did that alrdy and nothing pops up when the crash happens

              Resistance Is Futile. Your biological and technological distinctiveness will be added to our own.

              1 Reply Last reply
              0
              • jsulmJ jsulm

                You should run a debug build through the debugger to see where it crashes

                O Offline
                O Offline
                onimusha
                wrote on last edited by
                #7

                @jsulm I just want to know if there is something wrong in my code that could cause the crash besides my fuzzy logic to write code and algorithms. Other than that i think its my windows 7 machine.

                Resistance Is Futile. Your biological and technological distinctiveness will be added to our own.

                1 Reply Last reply
                0
                • O Offline
                  O Offline
                  onimusha
                  wrote on last edited by
                  #8

                  I think the problem lies in windows asynchronous tasks...... not being able to read the buffer properly while taking care of other tasks like repainting the window i'm currently moving, as a result my QVector goes out of index.

                  Resistance Is Futile. Your biological and technological distinctiveness will be added to our own.

                  1 Reply Last reply
                  0

                  • Login

                  • Login or register to search.
                  • First post
                    Last post
                  0
                  • Categories
                  • Recent
                  • Tags
                  • Popular
                  • Users
                  • Groups
                  • Search
                  • Get Qt Extensions
                  • Unsolved