Qt random crash

Hi, so here is the problem.

I made an ecosystem simulation with Qt.

The simulation is perfectly working on 800x800m maps, but I don't know why, when I go over this size, I've a random crash happening at a random place (with cout, I just saw that sometimes it crashes after a point, but sometimes it crashes before...).

The only thing I'm sure about is that it never pass again in my slotted function (called withn a timer and which is working with smaller map).
1
2
3
4
5
6
7
8
void Widget::stepEcosys() {
    if (_ecosys != nullptr) {
        _ecosys->step(true); // sometimes crash happen inside this function
        // sometimes happen between these both functions
        this->update();
        // sometimes get here but never loop again
    }
}


Thank you for help.
Edit: My code is pretty long so I don't know what to post, so don't hesitate to ask to me.
Last edited on
Is it possible that _ecosys can be pointing to just random memory, or to an object that has already been deleted? Do you have a guarantee that it will always either be nullptr, or that the object it points to will never have been destroyed?


_ecosys->step(true); // sometimes crash happen inside this function
Well what code is inside that function? On what line inside that function is the crash?
Last edited on
There's only one instance of Ecosys and no delete of it (I'm sure of that).

When I say the program is crashing inside the step() function, well there's no precise location, that's totally random. Here's the code if it may help you:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
void Ecosys::step(bool debug) {
    if (_plants.size() == 0) return;

    _timeElapsed += _timelapsePerStep;

    // -- perf --
    typedef std::chrono::high_resolution_clock Clock;
    typedef std::chrono::milliseconds milliseconds;
    // --

    doGrowth();
    doReproduce();
    Clock::time_point t0 = Clock::now();
    Clock::time_point t1;
    milliseconds ms;

    std::vector<std::thread> threads;

    std::vector<std::vector<Plant*>> pointerMap;
    for (unsigned int i(0); i < (unsigned) _height; ++i) {
        pointerMap.push_back(std::vector<Plant*>((unsigned) _width, nullptr));
    }
    for (unsigned int i(0); i < _plants.size(); ++i) {
        pointerMap[(unsigned) _plants[i].getPosition().getY()][(unsigned) _plants[i].getPosition().getX()] = &_plants[i];
    }
    std::sort(_plants.begin(), _plants.end(), [](const Plant & a, const Plant & b){return a.getSize() > b.getSize();});

    const int nbCores((int) std::thread::hardware_concurrency());

    for (int i(0); i < nbCores; ++i) {
        int value = (int) (_plants.size() / (unsigned long long) nbCores);
        int end = value * (i + 1);
        if (i >= nbCores - 1) end = (int) _plants.size();
        threads.push_back(std::thread(setConflicts, value * i,
                                      end,
                                      std::ref(pointerMap),
                                      std::ref(_plants),
                                      _width,
                                      _height));
    }

    for (auto & t: threads) t.join();

    // -- perf --
    t1 = Clock::now();
    ms = std::chrono::duration_cast<milliseconds>(t1 - t0);
    // --

    if (debug) std::cout << (int) ms.count() << "ms" << std::endl;

    for (unsigned int i(0); i < _plants.size(); ++i) {
        if (_plants[i].getState() == __DEAD__ || _plants[i].getAge() > _plants[i].getMaxAge() * YEAR_DURATION) {
            _plants.erase(_plants.begin() + i);
            --i;
        }
    }
}
Well, line 24 looks dubious. Next: On line 36 you send the local variable pointerMap as a reference to a thread but it will be invalid as soon as step(...) ends. Line 53 doesn't make it anyway better...
Also, just wanted to say, don't start identifiers or macros with 2 underscores (e.g. __DEAD__) or one underscore followed by a capital letter. They are reserved by the standard.
@coder777
I'm calling a join() for each thread at line 42, so there's no reason the function ends before threads. Or maybe I missunderstood what you wanted to say.

@Ganado
Thank you for the tip, I though underscores where some kind of convention of naming.
Topic archived. No new replies allowed.