Не могу найти ошибку при проходе по std::vector<std::shared_ptr<MyClass> >

248
01 декабря 2017, 06:12

Не могу понять, почему в вот таком классе возникает ошибка:

// simulation_box_widget.hpp
class SimulationBoxWidget : public QWidget {
    Q_OBJECT
public:
    SimulationBoxWidget(std::shared_ptr<SimulationBox> simulationBox_ptr);
public slots:
    void updateParticlesSystem();
protected:
    void paintEvent(QPaintEvent *event);
private:
    QTimer* _timer_ptr_particlesSystem;
    std::shared_ptr<SimulationBox> _simulationBox_ptr;
};

Реализую методы максимально просто:

// simulation_box_widget.cpp
SimulationBoxWidget::SimulationBoxWidget(std::shared_ptr<SimulationBox> simulationBox_ptr) {
    _simulationBox_ptr = simulationBox_ptr;
   // когда пишу так, то ошибки нет
   //_simulationBox_ptr->update();
    _timer_ptr_particlesSystem = new QTimer(this);
    _timer_ptr_particlesSystem->setInterval(10);
    QObject::connect(_timer_ptr_particlesSystem,
                     SIGNAL(timeout()),
                     this,
                     SLOT(updateParticlesSystem()));
    _timer_ptr_particlesSystem->start();
}
void SimulationBoxWidget::updateParticlesSystem() {
    // когда пишу так, ошибка есть
    //_simulationBox_ptr->update();
    this->update();
}
void SimulationBoxWidget::paintEvent(QPaintEvent *event) {}

Подскажите, пожалуйста, почему, когда пишу

_simulationBox_ptr->update()

в конструкторе, метод срабатывает (пробовал вызывать его много раз в цикле, тоже работает, т.е. видимо стабильно нет ошибки), а в SimulationBoxWidget::updateParticlesSystem() точно так же уже написать не выходит. На всякий случай, вызываемый метод:

// particles_system.cpp
void ParticlesSystem::update() {
    std::vector<std::shared_ptr<Particle> > particle_ptrs;
    particle_ptrs.reserve(2);
    for (auto p = _particle_ptrs.begin(); p != _particle_ptrs.end(); ++p) {
        for (auto p1 = p; p1 != _particle_ptrs.end(); ++p1) {
            if (p == p1)
                continue;
            particle_ptrs[0] = std::make_shared<Particle>(**p);
            }
        }
    return;
}

В valgrind:

==10830== Conditional jump or move depends on uninitialised value(s)
==10830==    at 0x403B19: ParticlesSystem::update() (in /home/anton/Git folder/Other/CppMD/md)
==10830==    by 0x4044BC: SimulationBoxWidget::updateParticlesSystem() (in /home/anton/Git folder/Other/CppMD/md)
==10830==    by 0x590E468: QMetaObject::activate(QObject*, int, int, void**) (in /home/anton/Qt5.9.1/5.9.1/gcc_64/lib/libQt5Core.so.5.9.1)
==10830==    by 0x591AC56: QTimer::timeout(QTimer::QPrivateSignal) (in /home/anton/Qt5.9.1/5.9.1/gcc_64/lib/libQt5Core.so.5.9.1)
==10830==    by 0x591AF27: QTimer::timerEvent(QTimerEvent*) (in /home/anton/Qt5.9.1/5.9.1/gcc_64/lib/libQt5Core.so.5.9.1)
==10830==    by 0x590F37A: QObject::event(QEvent*) (in /home/anton/Qt5.9.1/5.9.1/gcc_64/lib/libQt5Core.so.5.9.1)
==10830==    by 0x4F8D4BB: QApplicationPrivate::notify_helper(QObject*, QEvent*) (in /home/anton/Qt5.9.1/5.9.1/gcc_64/lib/libQt5Widgets.so.5.9.1)
==10830==    by 0x4F948E6: QApplication::notify(QObject*, QEvent*) (in /home/anton/Qt5.9.1/5.9.1/gcc_64/lib/libQt5Widgets.so.5.9.1)
==10830==    by 0x58E3EB7: QCoreApplication::notifyInternal2(QObject*, QEvent*) (in /home/anton/Qt5.9.1/5.9.1/gcc_64/lib/libQt5Core.so.5.9.1)
==10830==    by 0x59355FD: QTimerInfoList::activateTimers() (in /home/anton/Qt5.9.1/5.9.1/gcc_64/lib/libQt5Core.so.5.9.1)
==10830==    by 0x5935DE0: ??? (in /home/anton/Qt5.9.1/5.9.1/gcc_64/lib/libQt5Core.so.5.9.1)
==10830==    by 0x9EED196: g_main_context_dispatch (in /lib/x86_64-linux-gnu/libglib-2.0.so.0.4800.2)
==10830== 
==10830== Use of uninitialised value of size 8
==10830==    at 0x403A98: ParticlesSystem::update() (in /home/anton/Git folder/Other/CppMD/md)
==10830==    by 0x4044BC: SimulationBoxWidget::updateParticlesSystem() (in /home/anton/Git folder/Other/CppMD/md)
==10830==    by 0x590E468: QMetaObject::activate(QObject*, int, int, void**) (in /home/anton/Qt5.9.1/5.9.1/gcc_64/lib/libQt5Core.so.5.9.1)
==10830==    by 0x591AC56: QTimer::timeout(QTimer::QPrivateSignal) (in /home/anton/Qt5.9.1/5.9.1/gcc_64/lib/libQt5Core.so.5.9.1)
==10830==    by 0x591AF27: QTimer::timerEvent(QTimerEvent*) (in /home/anton/Qt5.9.1/5.9.1/gcc_64/lib/libQt5Core.so.5.9.1)
==10830==    by 0x590F37A: QObject::event(QEvent*) (in /home/anton/Qt5.9.1/5.9.1/gcc_64/lib/libQt5Core.so.5.9.1)
==10830==    by 0x4F8D4BB: QApplicationPrivate::notify_helper(QObject*, QEvent*) (in /home/anton/Qt5.9.1/5.9.1/gcc_64/lib/libQt5Widgets.so.5.9.1)
==10830==    by 0x4F948E6: QApplication::notify(QObject*, QEvent*) (in /home/anton/Qt5.9.1/5.9.1/gcc_64/lib/libQt5Widgets.so.5.9.1)
==10830==    by 0x58E3EB7: QCoreApplication::notifyInternal2(QObject*, QEvent*) (in /home/anton/Qt5.9.1/5.9.1/gcc_64/lib/libQt5Core.so.5.9.1)
==10830==    by 0x59355FD: QTimerInfoList::activateTimers() (in /home/anton/Qt5.9.1/5.9.1/gcc_64/lib/libQt5Core.so.5.9.1)
==10830==    by 0x5935DE0: ??? (in /home/anton/Qt5.9.1/5.9.1/gcc_64/lib/libQt5Core.so.5.9.1)
==10830==    by 0x9EED196: g_main_context_dispatch (in /lib/x86_64-linux-gnu/libglib-2.0.so.0.4800.2)
==10830== 
==10830== Invalid read of size 4
==10830==    at 0x403A98: ParticlesSystem::update() (in /home/anton/Git folder/Other/CppMD/md)
==10830==    by 0x4044BC: SimulationBoxWidget::updateParticlesSystem() (in /home/anton/Git folder/Other/CppMD/md)
==10830==    by 0x590E468: QMetaObject::activate(QObject*, int, int, void**) (in /home/anton/Qt5.9.1/5.9.1/gcc_64/lib/libQt5Core.so.5.9.1)
==10830==    by 0x591AC56: QTimer::timeout(QTimer::QPrivateSignal) (in /home/anton/Qt5.9.1/5.9.1/gcc_64/lib/libQt5Core.so.5.9.1)
==10830==    by 0x591AF27: QTimer::timerEvent(QTimerEvent*) (in /home/anton/Qt5.9.1/5.9.1/gcc_64/lib/libQt5Core.so.5.9.1)
==10830==    by 0x590F37A: QObject::event(QEvent*) (in /home/anton/Qt5.9.1/5.9.1/gcc_64/lib/libQt5Core.so.5.9.1)
==10830==    by 0x4F8D4BB: QApplicationPrivate::notify_helper(QObject*, QEvent*) (in /home/anton/Qt5.9.1/5.9.1/gcc_64/lib/libQt5Widgets.so.5.9.1)
==10830==    by 0x4F948E6: QApplication::notify(QObject*, QEvent*) (in /home/anton/Qt5.9.1/5.9.1/gcc_64/lib/libQt5Widgets.so.5.9.1)
==10830==    by 0x58E3EB7: QCoreApplication::notifyInternal2(QObject*, QEvent*) (in /home/anton/Qt5.9.1/5.9.1/gcc_64/lib/libQt5Core.so.5.9.1)
==10830==    by 0x59355FD: QTimerInfoList::activateTimers() (in /home/anton/Qt5.9.1/5.9.1/gcc_64/lib/libQt5Core.so.5.9.1)
==10830==    by 0x5935DE0: ??? (in /home/anton/Qt5.9.1/5.9.1/gcc_64/lib/libQt5Core.so.5.9.1)
==10830==    by 0x9EED196: g_main_context_dispatch (in /lib/x86_64-linux-gnu/libglib-2.0.so.0.4800.2)
==10830==  Address 0xe is not stack'd, malloc'd or (recently) free'd
==10830== 
==10830== 
==10830== Process terminating with default action of signal 11 (SIGSEGV)
==10830==  Access not within mapped region at address 0xE
==10830==    at 0x403A98: ParticlesSystem::update() (in /home/anton/Git folder/Other/CppMD/md)
==10830==    by 0x4044BC: SimulationBoxWidget::updateParticlesSystem() (in /home/anton/Git folder/Other/CppMD/md)
==10830==    by 0x590E468: QMetaObject::activate(QObject*, int, int, void**) (in /home/anton/Qt5.9.1/5.9.1/gcc_64/lib/libQt5Core.so.5.9.1)
==10830==    by 0x591AC56: QTimer::timeout(QTimer::QPrivateSignal) (in /home/anton/Qt5.9.1/5.9.1/gcc_64/lib/libQt5Core.so.5.9.1)
==10830==    by 0x591AF27: QTimer::timerEvent(QTimerEvent*) (in /home/anton/Qt5.9.1/5.9.1/gcc_64/lib/libQt5Core.so.5.9.1)
==10830==    by 0x590F37A: QObject::event(QEvent*) (in /home/anton/Qt5.9.1/5.9.1/gcc_64/lib/libQt5Core.so.5.9.1)
==10830==    by 0x4F8D4BB: QApplicationPrivate::notify_helper(QObject*, QEvent*) (in /home/anton/Qt5.9.1/5.9.1/gcc_64/lib/libQt5Widgets.so.5.9.1)
==10830==    by 0x4F948E6: QApplication::notify(QObject*, QEvent*) (in /home/anton/Qt5.9.1/5.9.1/gcc_64/lib/libQt5Widgets.so.5.9.1)
==10830==    by 0x58E3EB7: QCoreApplication::notifyInternal2(QObject*, QEvent*) (in /home/anton/Qt5.9.1/5.9.1/gcc_64/lib/libQt5Core.so.5.9.1)
==10830==    by 0x59355FD: QTimerInfoList::activateTimers() (in /home/anton/Qt5.9.1/5.9.1/gcc_64/lib/libQt5Core.so.5.9.1)
==10830==    by 0x5935DE0: ??? (in /home/anton/Qt5.9.1/5.9.1/gcc_64/lib/libQt5Core.so.5.9.1)
==10830==    by 0x9EED196: g_main_context_dispatch (in /lib/x86_64-linux-gnu/libglib-2.0.so.0.4800.2)
==10830==  If you believe this happened as a result of a stack
==10830==  overflow in your program's main thread (unlikely but
==10830==  possible), you can try to increase the size of the
==10830==  main thread stack using the --main-stacksize= flag.
==10830==  The main thread stack size used in this run was 8388608.
==10830== 
==10830== HEAP SUMMARY:
==10830==     in use at exit: 2,718,827 bytes in 22,033 blocks
==10830==   total heap usage: 323,823 allocs, 301,790 frees, 22,753,469 bytes allocated
==10830== 
==10830== LEAK SUMMARY:
==10830==    definitely lost: 196,332 bytes in 4,089 blocks
==10830==    indirectly lost: 58 bytes in 1 blocks
==10830==      possibly lost: 1,093,116 bytes in 3,926 blocks
==10830==    still reachable: 1,366,673 bytes in 13,503 blocks
==10830==                       of which reachable via heuristic:
==10830==                         length64           : 3,792 bytes in 69 blocks
==10830==                         newarray           : 2,112 bytes in 52 blocks
==10830==         suppressed: 0 bytes in 0 blocks
==10830== Rerun with --leak-check=full to see details of leaked memory
==10830== 
==10830== For counts of detected and suppressed errors, rerun with: -v
==10830== Use --track-origins=yes to see where uninitialised values come from
==10830== ERROR SUMMARY: 4090 errors from 3 contexts (suppressed: 0 from 0)

Я не понимаю, о какой неинициализированной переменной идёт речь и почему этой ошибки нет, если ParticlesSystem::update() вызывать из конструктора моего виджета. Помогите, пожалуйста.

Answer 1

После particle_ptrs.reserve(2); размер particle_ptrs остается равен 0, и вызов particle_ptrs[0] = std::make_shared приводит к выходу за пределы массива. И вообще непонятно зачем делать std::vector<std::shared_ptr<Particle> > когда в нем заполняется только один элемент? Может там должен был быть emplace_back? Кроме того, у класса Particle должен быть рабочий конструктор копирования.

READ ALSO
Перегрузка операции ++ для класса матриц в C++

Перегрузка операции ++ для класса матриц в C++

Я создал класс матриц и перегрузил для него операцию ++ (прибавление к матрице единичной матрицы), но почему то программа не работает, при запуске...

280
Как создаётся файл .AVI и/или .MJPG из jpeg-кадров на С++?

Как создаётся файл .AVI и/или .MJPG из jpeg-кадров на С++?

В программе на C++ идёт непрерывный поток кадров в формате jpeg (снимает вебкамера)Кадры на диск не попадают, всё в буфере

261
C++ недопустимое количество параметров в команде xcopy

C++ недопустимое количество параметров в команде xcopy

Думаю, вы не учли, что обратный слеш внутри строковых литералов имеет особое значениеЛибо заэкранируйте их:

371
Как &ldquo;рисовать&rdquo; в командной строке windows?

Как “рисовать” в командной строке windows?

В линуксе консольные приложения часто выводят свой прогресс подобием такого: [####___] 50%, при этом надпись "обновляется" на том же месте в терминале,...

284