PDA

View Full Version : Invalid parameter passed to C runtime function



Satansoft
29th November 2014, 10:26
Hi everybody,

have some trouble with Runtime library on step run of application (compiling was successful, build too) but when I press Start have a crash with this tags:


Invalid parameter passed to C runtime function.
Invalid parameter passed to C runtime function.
terminate called after throwing an instance of ‘std::system_error’ what(): Invalid argument
QObject::killTimers: timers cannot be stopped from another thread
Use: Qt 5.3 win MinGW 4.8 ×32 but run on x64 system, maybe problem here but i’m not sure
or because I try to combine c++11 code with Qt, but not sure too, because Qt traslate all it code to C++…

cannibals.h

#ifndef CANNIBALS_H
#define CANNIBALS_H
#include <thread>
#include <mutex>
#include <time.h>
#include <windows.h>
#define M 100

#include <QObject>

class Cannibals : public QObject
{
Q_OBJECT
public:
explicit Cannibals(QObject *parent = 0);
void Dinner_a(int);

private:
void Cooking();
void Dinner();
std::thread Cook;
std::mutex eating;
int food=10;

signals:
void NumberChanged(int);

public slots:

};

#endif // CANNIBALS_H
cannibals.cpp

#include "cannibals.h"

Cannibals::Cannibals(QObject *parent) :
QObject(parent)
{
}

void Cannibals::Cooking()
{
food=M;
}

void Cannibals::Dinner_a(int z)
{
eating.lock();
for(int i=0; i<z;i++){
Dinner();}
eating.unlock();
}

void Cannibals::Dinner()
{
if(food!=0){
emit NumberChanged(food);
--food;}
else
Cook = std::thread(&Cannibals::Cooking, this);
Cook.join();

Sleep(rand() 00);
}
mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include "cannibals.h"
#include <ui_mainwindow.h>
#include <QMainWindow>
#include <thread>
#define N 20
#define M 100
#define P (M/N)

namespace Ui {
class MainWindow;}

class MainWindow : public QMainWindow
{
Q_OBJECT

public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
Cannibals *Foo;
std::thread Cannibal[N];

private slots:
void on_pushButton_clicked();

private:
Ui::MainWindow *ui;

public slots:
void OnNumberChanged (int);
};

#endif // MAINWINDOW_H
mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
Foo = new Cannibals();
connect(Foo,SIGNAL(NumberChanged(int)),this,SLOT(O nNumberChanged(int)));
}

MainWindow::~MainWindow()
{
delete ui;
}

void MainWindow::on_pushButton_clicked()
{

for(int i=0;i<N;i++)
{
Cannibal[i] = std::thread(&Cannibals::Dinner_a, Foo, P);
}

for(int i=0;i<N;i++)
{
Cannibal[i].join();
}
}

void MainWindow::OnNumberChanged(int Num)
{
ui->listWidget->clear();
ui->pushButton->setEnabled(false);
ui->listWidget->addItem(QString(Num) + " cannibal ate");
}

wysota
29th November 2014, 13:20
Is this some kind of academic exercise or does the example have any practical goal? What is the point of all those threads?

Satansoft
29th November 2014, 13:28
Is this some kind of academic exercise or does the example have any practical goal? What is the point of all those threads?
Yes, this is exercise to practice in multithreading, but GUI is required condition and I chose Qt. About point: 20 threads - children and 1 thread - mother, children eat plumps, and when bowl is empty call mom to fill it. Amount of children and plumps is variables...

anda_skoa
29th November 2014, 13:52
The Qt signal/slot code might not recognize the non-Qt thread correctly and chose to handle your connect() as a DirectConnection instead of QueuedConnection.

Try it with explicitly specifying that


connect(Foo,SIGNAL(NumberChanged(int)),this,SLOT(O nNumberChanged(int)), Qt::QueuedConnection);


Cheers,
_

Satansoft
29th November 2014, 14:03
10772



connect(Foo,SIGNAL(NumberChanged(int)),this,SLOT(O nNumberChanged(int)), Qt::QueuedConnection);


This is have no effect, add full project for tests.

wysota
29th November 2014, 14:31
Yes, this is exercise to practice in multithreading, but GUI is required condition and I chose Qt. About point: 20 threads - children and 1 thread - mother, children eat plumps, and when bowl is empty call mom to fill it. Amount of children and plumps is variables...

I think you overcomplicated the code. And shouldn't the producer be a thread living all the time just waiting for the consumers to tell it to start producing? Right now you start a thread only to set a variable and then the thread dies. With the architecture you have there is completely no benefit from having threads so I doubt this is what your professor had in mind.

Satansoft
29th November 2014, 14:43
I think you overcomplicated the code. And shouldn't the producer be a thread living all the time just waiting for the consumers to tell it to start producing? Right now you start a thread only to set a variable and then the thread dies. With the architecture you have there is completely no benefit from having threads so I doubt this is what your professor had in mind.

Perhaps and overcomplicated, but task must be solved. I chose C++11 methods by reason of transparency, have any ideas to solve it?

wysota
29th November 2014, 15:33
Perhaps and overcomplicated, but task must be solved. I chose C++11 methods by reason of transparency, have any ideas to solve it?

If it is your school task then we cannot interfere with it, we can only give you hints regarding the use of Qt. I can only suggest to divide your code into classes -- one for the producer, one for the consumer and one for management and user-interface. Then it should be much easier for you to comprehend what is where. If using std::thread is not an explicit requirement then you might want to switch to using QThread.