Absturz in der paint routine

Alles rund um die Programmierung mit Qt
Antworten
iso8859-1
Beiträge: 25
Registriert: 8. März 2009 11:02

Absturz in der paint routine

Beitrag von iso8859-1 »

Hi,

ich habe eine paint routine für ein eigenes Widget die mir ständig mit "Invalid parameter passed to C runtime function." abstürzt. Die routine sieht so aus:

Code: Alles auswählen

void CuteHexEditorWidget::PaintOffsets(QPainter &painter, bool eightByteOffsets, boost::uint64_t startOffset)
{
    auto height = viewport()->height();

    auto font = painter.fontMetrics();
    int width = 4*font.averageCharWidth();
    if (eightByteOffsets)
    {
        width += 4*font.averageCharWidth();
    }
    width += 2*OffsetStartInPixel();
    painter.fillRect(0,0,width,height,GetOffsetBackgroundGolor());

    unsigned int linesToPaint = LinesToPaint(height,LineHeight(),LinePitch());


    for (unsigned int i=startOffset; i<startOffset+linesToPaint; ++i)
    {
        QPoint lineStart(OffsetStartInPixel(), LineHeight()+i*(LineHeight()+LinePitch()));
        QString line = "Test";
        if (eightByteOffsets)
        {
            for (auto k=15; k>=8; ++k)
            {
                line.append(convert(i>>k*4));
            }
        }
        for (auto k=7; k>=0; ++k)
        {
            line.append(convert(i>>k*4));
        }
        painter.drawText(lineStart, line);
    }
}
wobei convert so definiert ist:

Code: Alles auswählen

char CuteHexEditorWidget::convert(boost::uint32_t value)
{
    value = value & 0x0f;
    switch (value)
    {
    case 0: return '0';
    case 1: return '1';
    case 2: return '2';
    case 3: return '3';
    case 4: return '4';
    case 5: return '5';
    case 6: return '6';
    case 7: return '7';
    case 8: return '8';
    case 9: return '9';
    case 10: return 'a';
    case 11: return 'b';
    case 12: return 'c';
    case 13: return 'd';
    case 14: return 'e';
    case 15: return 'f';
    }
    return 'x';
}
sobald ich das if und die for-schleife auskommentiere, funktioniert es. Woran kann das liegen?
iso8859-1
Beiträge: 25
Registriert: 8. März 2009 11:02

Re: Absturz in der paint routine

Beitrag von iso8859-1 »

Fehler gefunden ++ statt --

So ist es richtig (bis auf das die Berechnung noch nicht stimmt da 2 chars / Byte benötigt werden.

Code: Alles auswählen

void CuteHexEditorWidget::PaintOffsets(QPainter &painter, bool eightByteOffsets, boost::uint64_t startOffset)
{
    auto height = viewport()->height();

    auto font = painter.fontMetrics();
    int width = 4*font.averageCharWidth();
    if (eightByteOffsets)
    {
        width += 4*font.averageCharWidth();
    }
    width += 2*OffsetStartInPixel();
    painter.fillRect(0,0,width,height,GetOffsetBackgroundGolor());

    unsigned int linesToPaint = LinesToPaint(height,LineHeight(),LinePitch());


    for (unsigned int i=startOffset; i<startOffset+linesToPaint; ++i)
    {
        QPoint lineStart(OffsetStartInPixel(), LineHeight()+i*(LineHeight()+LinePitch()));
        QString line = "Test";
        if (eightByteOffsets)
        {
            for (auto k=15; k>=8; --k)
            {
                line.append(convert(i>>k*4));
            }
        }
        for (auto k=7; k>=0; --k)
        {
            line.append(convert(i>>k*4));
        }
        painter.drawText(lineStart, line);
    }
}
Zuletzt geändert von iso8859-1 am 20. August 2012 14:57, insgesamt 2-mal geändert.
brax
Beiträge: 208
Registriert: 11. Mai 2010 11:22

Re: Absturz in der paint routine

Beitrag von brax »

Nur als Hinweis:
"int" ist kürzer als "auto" und würde den Code in den beiden Schleifen durchaus lesbarer gestalten. Ansonsten ist auto echt ein nettes neues Feature, aber das würde ich als auto-Mißbrauch empfinden.
Nur meine Meinung....
iso8859-1
Beiträge: 25
Registriert: 8. März 2009 11:02

Re: Absturz in der paint routine

Beitrag von iso8859-1 »

hi,

auto ist gerade für die Schleifen gut. Hier zum vergleich:

Code: Alles auswählen

for (std::vector<boost::shared_ptr<CMyClass>>::const_iterator i = vec.cbegin(); i!=vec.cend(); ++i)
{
    ...
}
oder etas leserlicher:

Code: Alles auswählen

typedef std::vector<boost::shared_ptr<CMyClass>>::const_iterator citerator
for (citerator i = vec.cbegin(); i!=vec.cend(); ++i)
{
    ...
}
und nun mit auto:

Code: Alles auswählen

for (auto i = vec.cbegin(); i!=vec.cend(); ++i)
{
    ...
}
Da die Schleife mit int nur ein "Sonderfall" für mich ist und meist eh über iteratoren "geschleift" wird, schreibe ich grundsätzlich mit auto es sei denn es gibt sonst eine Warning. Wobei man dann diskutieren kann ob man so was schreibt

Code: Alles auswählen

for (auto i = static_cast<unsigned int>(0); i < 5; ++i)
{
    ...
}
[code]

Und kürzer ist für mich nie ein Argument. Code wird häufiger gelesen als geschrieben - also Klarheit vor Kürze (wobei manchmal beides geht - siehe vector oben). Auch hier nur meine Meinung und danke für die Anregung darüber nachzudenken.
brax
Beiträge: 208
Registriert: 11. Mai 2010 11:22

Re: Absturz in der paint routine

Beitrag von brax »

Bei den Iteratoren gebe ich Dir absolut recht, das war auch (soweit mir von Mitgliedern des C++ Kommitees berichtet wurde) einer der Punkte, an die bei der Einführung von auto gedacht wurde.

In dem Code wäre aber das auto durch ein einfaches int zu ersetzen. Wenn ich in einer Schleife "auto" sehe, denke ich zuerst an einen Iterator und daher "stolperte" ich etwas beim Lesen Deines Codes (von wegen "Klarheit statt Kürze" - was natürlich an sich ein sehr löbliches Prinzip ist). Wie gesagt, war nur als Denkanstoß gedacht, als den Du das ja auch verstanden hast ;)
Antworten