1

I develop a cross platform Qt program which plots a polyline on a QGraphicsScene:

QPolygonF polygon;
//Init polygon here
for(int i = 0; i < (polygon.size()-1); i++) {
  float x1 = polygon[i].x();
  float y1 = polygon[i].y();
  float x2 = polygon[i+1].x();
  float y2 = polygon[i+1].y();
  QGraphicsLineItem* item = new QGraphicsLineItem(x2, y2, x1, y1);
  item->setPen(QPen(QBrush(color), 2));
  item->setZValue(30);
  item->setData(0, QVariant((int)value));
  addItem(item);
}

The program crashes on windows when it recieves the following values:

 float x1 = 249.573;
 float y1 = 183.471;
 float x2 = 303.983;
 float y2 = 183.45;

This polyline is composed of an almost horizontal line. The crash doesn't occur when the line is horizontal or the absolute difference between y1 and y2 is 0 or larger than 0.5. It doesn't crash on Ubuntu.

When I change the polyline to a polygon the program doesn't crash. My best, but ugly solution was to draw the polyline as a polygon - append the same points twice to the polygon:

QPolygonF polygon;
//Init polygon here
for(int i = polygon.size()-1; i > 0; i--) {
   QPointF point(polygon[i].x(), polygon[i].y());
   polygon.append(point);
}
QGraphicsPolygonItem* item = new QGraphicsPolygonItem(polygon);
item->setPen(QPen(QBrush(color), 2));
item->setZValue(30);
item->setData(0, QVariant((int)value));
addItem(item);

I tried to recreate the bug in a small and independent program, that plots a line with the same coordinates on a QGraphicScene. No crash was observed.

Why is this crash happening? Is there a more prettier solution to this bug?

By the way, the call stack in VS2008 debugger tells me that the crash is in malloc.c in msvcr90.dll which is called by QtGui4.dll.

Technicals:

Qt version: 4.7.0

OS: Windows 7 and Ubuntu

White Zebra
  • 309
  • 1
  • 5
  • 15
  • 1
    Why is addItem(item); outside the loop in your code? – Frédéric Terrazzoni Jun 10 '12 at 08:17
  • As Frédéric points out, the addItem is in the wrong place. The `item` variable inside the loop falls out of scope and the `item` variable used in the addItem call has nothing to do with the QGraphicsLineItem created inside the loop. –  Jun 10 '12 at 08:42
  • 1
    A crash in malloc generally means you have heap corruption. The corruption itself could potentially come from anywhere in your code. – Michael Slade Jun 10 '12 at 09:18
  • @FrédéricTERRAZZONI you're right - the addItem is indeed inside the loop. I fixed this in the edit. – White Zebra Jun 10 '12 at 11:45
  • @MichaelSlade Do you have any idea how can a heap corruption happen in windows and not in linux in this case? – White Zebra Jun 10 '12 at 11:48
  • @WhiteZebra: You can use `Application Verifier` to debug the corruption. It will trigger a breakpoint whenever a heap corruption is detected. – Synxis Jun 10 '12 at 12:26

1 Answers1

2

Did you know that there is also the QGraphicsPathItem? (QGraphicsPolygonItem is for closed polygons only, not for polylines. The path item is for general paths.)

You need to construct a QPainterPath from your QPolygon:

QPainterPath path;
if(polygon.size() > 0) // check this, because we use [0] outside the loop!
{
    path.moveTo(polygon[0]);
    for(int i = 1; i < polygon.size(); ++i) // starting from 1 (0 was a "moveTo")
       path.lineTo(polygon[i]);
}

Then make and use the path item:

QGraphicsPathItem* item = new QGraphicsPathItem(path);

// your additional code from above:
item->setPen(QPen(QBrush(color), 2));
item->setZValue(30);
item->setData(0, QVariant((int)value));

addItem(item);

But note that since your posted code seems to be error-free, there has to be a serious bug in your program (probably at a different (maybe related) position in the code), which you should fix anyway!

Probably there is a bug in the generation of the coordinates? Or some calculation even before generating the QPolygonF? Did you try commenting out the code which generates the item?

You could also try using valgrind alternative for Windows. See this Stackoverflow question for some tools.

Community
  • 1
  • 1
leemes
  • 44,967
  • 21
  • 135
  • 183
  • I wasn't familiar with QGraphicsPathItem - will try it now, thanks! I did run valgrind, but on linux - didn't get anything interesting enough. I'll check the valgrind alternatives, and hope that they find the bug... – White Zebra Jun 10 '12 at 12:29
  • Changed the code to use QPainterPath - the program is still crashing. Maybe both QGraphicsPathItem and QGraphicsLineItem basically draw a straight line in a similar way? – White Zebra Jun 11 '12 at 11:45
  • @WhiteZebra I think so. At least, you now know this class and improved your code in this point. :) So you have a bug at another position in your code... I prefer thinking hard and doing a lot of qDebugs over using tools like valgrind, as long as it is possible to find any memory leaks / double frees / whatever this way. So my advice: Carefully read your source code, think twice whenever you read some "dangerous" code, and do a lot of debug outputs. If this doesn't help, maybe the valgrind alternatives are your friend. Good luck finding the bug! ;) – leemes Jun 11 '12 at 11:51