-1

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?

Junior
  • 507
  • 5
  • 19
  • The right tool to solve such problems is your debugger. You should step through your code line-by-line *before* asking on Stack Overflow. For more help, please read [How to debug small programs (by Eric Lippert)](https://ericlippert.com/2014/03/05/how-to-debug-small-programs/). At a minimum, you should \[edit] your question to include a [Minimal, Complete, and Verifiable](http://stackoverflow.com/help/mcve) example that reproduces your problem, along with the observations you made in the debugger. – πάντα ῥεῖ Aug 30 '16 at 13:20
  • Lines that generates errors are already marked with comments. I obtained those using the debugger. Thanks anyway for the copy-paste guidelines. – Junior Aug 30 '16 at 13:28
  • Do you have a backtrace also maybe? Learn how to use your tools please. – πάντα ῥεῖ Aug 30 '16 at 13:30
  • 4
    You shouldn't ever use `malloc` for C++ classes. You could use `new` to directly allocate an array, though that is "outdated" style of coding C++, too. If you use `malloc`m you should then use so called "placement new" to initialize your structs. Also, using `typedef` like that is not necessary in C++. – hyde Aug 30 '16 at 13:42

2 Answers2

1

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 ...
}
hyde
  • 60,639
  • 21
  • 115
  • 176
1

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
    }
};
Kuba hasn't forgotten Monica
  • 95,931
  • 16
  • 151
  • 313