У меня есть эта структура:
typedef struct {
QPolygon polygon;
QRect position;
} form;
Я пытаюсь инициализировать forms
как показано ниже, но я получил ошибку ошибки сегментации:
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
}
Я тоже так пытаюсь:
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
Как я могу иметь полигон в структуре?
Сначала определите свою структуру следующим образом в C ++:
struct form { // note: Qt naming convention would use upper case first letter
QPolygon polygon;
QRect position;
};
В конце этого ответа есть более современная альтернатива, но сначала, чтобы напрямую исправить ваш 20-летний стиль C ++, напишите свой код следующим образом (вы не должны, но только для того, чтобы вы знали, как это сделать):
Для этого предположим, что у вас есть
form *forms;
Тогда вы могли бы сделать ваш код не сбой, если вы написали это так:
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));
}
Ваша ошибка может быть был, потому что ваш QPolygon
а также QRect
экземпляры внутри form
структуры не были правильно построены. Трудно сказать, что вы сделали, это было неопределенное поведение, обращаясь к неинициализированной памяти, как это. Кроме того, у вас было n==10
в первой итерации вашего цикла, которая находится за пределами допустимого диапазона индекса 0..9, который тоже мог бы потерпеть крах.
Кроме того, когда вы выделяете массив с new
, вы должен также удалите его как массив, чтобы элементы массива были должным образом разрушены:
delete[] forms;
В современном C ++ вам не нужно этого делать, вы будете использовать типы значений или умные указатели.
Наконец, более современная версия, которая намного проще и безопаснее, и вам не нужно беспокоиться об освобождении памяти и т. Д .:
std::vector<form> forms;int n = 10
forms = std::vector<form>(n); // assign a vector of length n to formswhile (n > 0) {
... contents of the loop are same as above ...
}
Поскольку вы пишете на C ++ 11, а не на C, ваш код должен быть намного проще. Используйте язык, который вы используете.
emplace_back
конструирует Form
экземпляр прямо внутри вектора: это самый быстрый способ сделать это. Вы также можете использовать push_back
, но это создает временный, который не дешево перемещается.
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
}
};