Programm stürzt ab.

Alles rund um die Programmierung mit Qt
Antworten
dolin93
Beiträge: 45
Registriert: 5. Mai 2012 21:35

Programm stürzt ab.

Beitrag von dolin93 »

Hallo,
nach dem das angehängte Programm einige Male fehlerfrei gelaufen ist, ging ich daran, Unnützes daraus zu entfernen und wollte es später erweitern. Leider stürzt es nun dauernd ab und ich kann den Fehler nicht finden. Vielleicht kann mir jemand helfen.filedownloader.h:

Code: Alles auswählen

class FileDownloader  : public QObject
{
    Q_OBJECT
public:
     FileDownloader(const QUrl &KUrl);
    virtual ~FileDownloader();
signals:
        void downloaded();
        void DataA(const QByteArray &m_DownloadedData);
// private slots:
public slots:
    void fileDownloaded(QNetworkReply* pReply);
private:
    QUrl kUrl;
    QNetworkAccessManager m_WebCtrl;
    QByteArray m_DownloadedData;
};

#endif // FILEDOWNLOADER_H
mainWidget.h:

Code: Alles auswählen

class mainWidget : public QWidget
{
    Q_OBJECT
public:
  mainWidget(const QByteArray &QBA);
  void helper(QString &result);
   QByteArray A;
   public slots:
  void Receiver(const QByteArray&);
  protected:
  void paintEvent(QPaintEvent *event);
   QUrl histUrl;
   QVector<float> CloseAdj;
   QVector<int> Volume;
   //QByteArray A;
};
#endif // WIDGET_H
YahooGUI1.pro:

Code: Alles auswählen

QT       += core gui

TARGET = YahooGUI1
CONFIG   += console
//CONFIG   -= app_bundle
TEMPLATE = app


SOURCES += main.cpp\
    filedownloader.cpp \
    mainwidget.cpp

QT += network

HEADERS += \
    filedownloader.h \
    mainwidget.h
Dateianhänge
mainwidget.cpp
(2 KiB) 301-mal heruntergeladen
filedownloader.cpp
(2.04 KiB) 298-mal heruntergeladen
main.cpp
(1.17 KiB) 287-mal heruntergeladen
MichaelS
Beiträge: 240
Registriert: 27. Dezember 2005 12:49

Re: Programm stürzt ab.

Beitrag von MichaelS »

Leider stürzt es nun dauernd ab
Was sagt der Debugger dazu?
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Re: Programm stürzt ab.

Beitrag von Christian81 »

Ich schätze er sagt dass es eine Assertion gibt weil man auf einen Index im QByteArray zugegriffen hat welcher hinter der Größe des ByteArrays liegt. Haufenweise ungeprüfte Index-Zugriffe im Code...
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
dolin93
Beiträge: 45
Registriert: 5. Mai 2012 21:35

Re: Programm stürzt ab.

Beitrag von dolin93 »

Hallo und vielen Dank für Eure Antworten!
Der Debugger meldet
Der Prozess wurde nach Erhalt eines Signals vom Betriebssystem angehalten.

Name des Signals :
SIGSEGV
Bedeutung :
Segmentation fault
Die Groesse des QByteArrays ist 7404, liegt also weit oberhalb der im Programm angegebenen 7000. Aus einem anderen Programm ohne graphische Darstellung kenne ich die Groessen der Arrays und Vektoren.
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Re: Programm stürzt ab.

Beitrag von Christian81 »

Der Debugger gibt einen Backtrace aus (Doku zum Debugger lesen, bei gdb ist es 'bt', bei MSVC gibt es ein extra Dockwidget 'Backtrace') dort sieht man wo genau er einen Fehler meldet. Bitte ein wenig mit den Grundlagen deiner IDE bschäftigen.

Ich sehe auch nirgends eine Begrenzung sondern nur Zugriffe ohne Prüfung ob es innerhalb der Größe des ByteArray ist. z.B. hier:

Code: Alles auswählen

while(m_DownloadedData[j]!='2')
       {j++;
       }
--> Wenn in deinem ByteArray keine '2' auftaucht, was wird dann wohl passieren. Das Gleiche Problem hast du an zig anderen Stellen genauso

oder auch im paintEvent:

Code: Alles auswählen

Vo=Volume[i]/1000000;
--> Volume ist ein Vector, welcher anfänglich natürlich keinen Inhalt hat, also auch hier das gleiche Problem
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
dolin93
Beiträge: 45
Registriert: 5. Mai 2012 21:35

Re: Programm stürzt ab.

Beitrag von dolin93 »

Vielen Dank für Deine Antwort!
Die Ursache des Problems ist aber, daß das QByteArray nicht mehr in mainwidget.cpp gelangt. Alles andere kann ich leicht korrigieren.main.cpp

Code: Alles auswählen

 int main(int argc, char *argv[])
    {
        QApplication a( argc, argv );
        char separator, step='d',tags;
        QString symbol="AAPL";
       int startDay=20,startMonth=6,startYear=2014,endDay=31, endMonth=12,endYear=2014,sM,eM;
       sM=startMonth-1;
       eM=endMonth-1;
       QUrl histUrl(QString("http://ichart.finance.yahoo.com/table.csv?s=%1&a=%2&b=%3&c=%4&d=%5&e=%6&f=%7&g=step&y=0&ignore=.cvs").arg(symbol).arg(sM).arg(startDay).arg(startYear).arg(eM).arg(endDay).arg(endYear),QUrl::TolerantMode);
       FileDownloader demo(histUrl);
         QByteArray B;
         demo.trans(B);
         qDebug("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%");
        qDebug(B);
        mainWidget w;
         QObject::connect(&demo,SIGNAL(DataA(const QByteArray&)),&w,
         SLOT(Receiver(const QByteArray &)));
         QString result;
         w.helper(result);
         qDebug(qPrintable(result));
         w.show();
       return a.exec();
       }
habe ich ein wenig verändert ebenso wie mainwidget.cpp

Code: Alles auswählen

mainWidget::mainWidget()
{
    setWindowTitle ( "paintEvent - Demo");
    resize( 1000, 400 );
}
void mainWidget::paintEvent ( QPaintEvent * event ) {
   QPainter painter(this);
   painter.begin( this );
   painter.setPen( QPen(Qt::blue, 2) );
    painter.drawLine(0,90,110,90);

   painter.setPen( QPen(Qt::green, 2) );
   int u,x1,ku,ku1,Vo,Vo1;
   for(int i=1;i<Vect;i++)
   {   u=i*2;
       x1=2+2*i;
       ku=CloseAdj[i];
       ku1=CloseAdj[i+1];
      painter.drawLine(u,ku,x1,ku1);      
   }
    painter.setPen( QPen(Qt::red, 2) );
   for(int i=1;i<Vect;i++)
   {   u=i*2;
       x1=2+2*i;
       Vo=Volume[i]/1000000;
       Vo1=Volume[i+1]/1000000;
       painter.drawLine(u,Vo,x1,Vo1);
   }
    painter.setPen(
   QPen(Qt::black, 5, Qt::DotLine, Qt::RoundCap));
   painter.drawRect( Koordinate,40,120,150 );
}
void mainWidget::Receiver(const QByteArray &QBA){
    qDebug(A);
    groesseA=A.size()-10;
    if(groesseA>40){
    int j=0;
           while(A[j]!='2')
           {j++;
           }
           QVector<QString> days;
           QVector<float> CloseAdj;
           QVector<int> Volume;
           for(int i=j;i<7100;i++)
           {QString day =" ";
           QString volume = " ";
           QString CloseAd =" ";
           qint32 volume_=0;
           float Close=0;
           for (int k=0;k<10;k++)
           {day+=A[i+k];
           }
           i+=9;
           while(A[i]!=',')
           {//qDebug(" Problem   bis Komma ");
            i++;
           }
           while(A[i+1]!=',')
            {i++;}
           while(A[i+2]!=',')
            {i++;}
           while(A[i+3]!=',')
            {i++;}
           while(A[i+4]!=',')
            {i++;}
           while(A[i+5]!=',')
            {volume+=A[i+5];
             i++;
            }
           while(((A[i+6]>='0' && A[i+6]<='9') || A[i+6]== '.')&& !(A[i+6]=='2' && A[i+7]=='0' && A[i+8]<='1' && A[i+9]<='5'))
           {CloseAd+=A[i+6];
           i++;
           }
           i+=6;
           Close=CloseAd.toFloat();
           days.append(day);
           CloseAdj.append(Close);
           volume_=volume.toInt();
           Volume.append(volume_);
           }
           int Vect=Volume.size();
     }
    Koordinate=160;
    return;
}

void mainWidget::helper(QString &result){
    result="Hallo";    
}
und filedownloader.cpp

Code: Alles auswählen

FileDownloader::FileDownloader(const QUrl &KUrl ) : kUrl(KUrl)
   {
       connect(&m_WebCtrl, SIGNAL(finished(QNetworkReply*)),
                   SLOT(fileDownloaded(QNetworkReply*)));
       QNetworkRequest request(kUrl);
       m_WebCtrl.get(request);
   }

   FileDownloader::~FileDownloader()
   {

   }

   void FileDownloader::fileDownloaded(QNetworkReply* pReply)
   {
       m_DownloadedData = pReply->readAll();
       pReply->deleteLater();
       emit downloaded();
       emit DataA(m_DownloadedData);
       qDebug("aaaaaaaaaaaaaaaaaaaaaaaaaa");
       //qDebug(m_DownloadedData);

       int j=0;
       while(m_DownloadedData[j]!='2')
       {j++;
       }
       QVector<QString> days;
       QVector<float> CloseAdj;
       QVector<int> Volume;
       for(int i=j;i<7100;i++)
       {QString day =" ";
       QString volume = " ";
       QString CloseAd =" ";
       qint32 volume_=0;
       float Close=0;
       for (int k=0;k<10;k++)
       {day+=m_DownloadedData[i+k];
       }
       i+=9;
       while(m_DownloadedData[i]!=',')
       {//qDebug(" Problem   bis Komma ");
        i++;
       }
       while(m_DownloadedData[i+1]!=',')
        {i++;}
       while(m_DownloadedData[i+2]!=',')
        {i++;}
       while(m_DownloadedData[i+3]!=',')
        {i++;}
       while(m_DownloadedData[i+4]!=',')
        {i++;}
       while(m_DownloadedData[i+5]!=',')
        {volume+=m_DownloadedData[i+5];
         i++;
        }
       while(((m_DownloadedData[i+6]>='0' && m_DownloadedData[i+6]<='9') || m_DownloadedData[i+6]== '.')&& !(m_DownloadedData[i+6]=='2' && m_DownloadedData[i+7]=='0' && m_DownloadedData[i+8]<='1' && m_DownloadedData[i+9]<='5'))
       {CloseAd+=m_DownloadedData[i+6];
       i++;
       }
       i+=6;
       Close=CloseAd.toFloat();
       days.append(day);
       CloseAdj.append(Close);
       volume_=volume.toInt();
       Volume.append(volume_);
       }
       int Groesse=Volume.size();
       std::cout<<"  Groesse="<<Groesse<<std::endl;
       for(int l=0;l<10;l++)
       {QString tag=days[l];
           qDebug(qPrintable(tag));
       }
       return ;
   }
   void FileDownloader::trans(QByteArray &B){
    B.append(m_DownloadedData);
    return;
   }
Das Programm stürzt zwar nicht mehr ab, aber man sieht, daß das QByteArray nicht in mainwidget.cpp gelangt. Daran hapert es.
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Re: Programm stürzt ab.

Beitrag von Christian81 »

Wie sollte es auch funktionieren? Die Daten werden asynchron heruntergeladen, Du versuchst aber sofort die Daten aus FileDownloader herauszulesen (trans()). Wie sollte das funktionieren? Signals und Slots hast Du ja schon entdeckt - warum benutzt Du sie dann nicht um die Daten nach dem Herunterladen in das MainWidget zu bekommen?
Und im MainWindget wir haben immer noch überall das Problem des ungeprüften Arrayzugriffs - sobald mal die Daten nicht so kommen wie Du es erwartest ist das Programm hinüber. Oder sobald paintEvent() vom MainWidget aufgerufen wird, aber das habe ich oben ja schon geschrieben...
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
dolin93
Beiträge: 45
Registriert: 5. Mai 2012 21:35

Re: Programm stürzt ab.

Beitrag von dolin93 »

Vielen Dank für Deine Antwort!
Connect(..........) außerhalb von main.cpp, also in filedownloader.cpp oder in mainwidget.cpp zu platzieren, wird mir wohl nicht viel helfen, da sowohl

Code: Alles auswählen

FileDownloader demo(histUrl);
als auch

Code: Alles auswählen

 mainWidget w ;
         w.show();
nichts bewirken wird, wenn es außerhalb von main.cpp steht.. Aus der Tatsache, daß ich von niemandem diesbezüglich einen Lösungsvorschlag erhalten habe, schließe ich, daß die Lösung auch für Fachleute nicht einfach ist. Daß es bei mir gelaufen ist, bis ich unvorsichtigerweise zu schnell Unnützes (und noch mehr) entfernte, war wohl Glück.
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Re: Programm stürzt ab.

Beitrag von Christian81 »

Ich verstehe deine letzte Antwort nicht - ich habe nie etwas dergleichen behauptet. Ich habe nur gesagt dass das connect() in main() korrekt ist und der weg über trans() und helper() nicht funktionieren *kann* ...
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
Antworten