Qt struct of QPolygon

428 Views Asked by At

I have this structure:

typedef struct {
    QPolygon polygon;
    QRect position;
} form;

I try to initialize forms like below but I got segmentation fault error:

int n = 10
forms = (form*) malloc(sizeof(form) * n);
while (n>0) {
   forms[n].position.setRect(0,0,0,0);
   forms[n].polygon=QPolygon(0); //error - segmentation fault
   forms[n].polygon = QPolygon(QRect(x, y, w, h)); //error - segmentation fault
}

I try like this also:

QPolygon v;
v = QPolygon(QRect(x, y, w, h)); //ok
v = QPolygon(QRect(x, y, w, h)); //ok
sprites[n].polygon = QPolygon(QRect(x, y, w, h)); //error - segmentation fault

How can I have a polygone into a struct?

2

There are 2 best solutions below

0
hyde On

First, define your struct like this in C++:

struct form { // note: Qt naming convention would use upper case first letter
    QPolygon polygon;
    QRect position;
};

At the end of this answer there is a more modern alternative, but first, to directly fix your 20 years old style C++, write your code like this (you shouldn't, but just so you know how to do it):

For this, lets assume you have

form *forms;

Then you could make your code not crash, if you wrote it like this:

int n = 10
forms = new form[n]; // bad style in modern C++, use std::vector instead
while (n > 0) {
   --n; // indexes go 9..0
   //forms[n].position.setRect(0,0,0,0); // constructor did this
   //forms[n].polygon=QPolygon(0); // constructor did this
   forms[n].polygon = QPolygon(QRect(x, y, w, h));
}

Your error might have been, because your QPolygon and QRect instances inside form structs were not properly constructed. Hard to say, what you did was undefined behavior, accessing uninitialized memory like that. Additionally, you had n==10 in your loop's first iteration, which is outside valid index range 0..9, that might have crashed too.


Additionally, when you allocate an array with new, you must also delete it as array, so that array elements get properly destructed:

delete[] forms;

With modern C++, you wouldn't need to do this, you'd use value types or smart pointers.


Finally, a more modern version, which is just all around easier and safer, and you don't need to worry about releasing memory, etc:

std::vector<form> forms;


int n = 10
forms = std::vector<form>(n); // assign a vector of length n to forms


while (n > 0) {
    ... contents of the loop are same as above ...
}
0
Kuba hasn't forgotten Monica On

Since you're writing C++11, not C, your code should be much simpler. Leverage the language you're using.

emplace_back constructs the Form instance right inside the vector: it's the fastest way to do it. You could also use push_back, but that constructs a temporary that's not cheaply movable.

struct Form {
    QPolygon polygon;
    QPoint position; // maybe you meant QRect boundingRect?
    Form(const QPolygon & polygon, const QPoint & position) :
        polygon{polygon}, position{position} {}
    Form() = default;
};

class Class {
    std::vector<Form> forms;
public:
    Class() {
        int x = 0;
        int y = 0;
        int w = 100;
        int h = 100;
        forms.reserve(20); // avoids copies as the vector grows
        for (int i = 0; i < 10; ++i)
            forms.emplace_back(QRect{x,y,w,h}, QPoint{x,y});
        for (int i = 0; i < 10; ++i)
            forms.push_back({QRect{x,y,w,h}, {x,y}}); // uniform initialization
    }
};