Seite 1 von 1

Absturz in der paint routine

Verfasst: 20. August 2012 10:28
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?

Re: Absturz in der paint routine

Verfasst: 20. August 2012 11:31
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);
    }
}

Re: Absturz in der paint routine

Verfasst: 20. August 2012 12:58
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....

Re: Absturz in der paint routine

Verfasst: 20. August 2012 14:55
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.

Re: Absturz in der paint routine

Verfasst: 20. August 2012 15:28
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 ;)