I ran across a problem that I don't really understand. I'm running this code in QTcreator in Lubuntu and the problem i have is explained after the code. This is a simple program that runs a few processes using forks that approximates Pi with the Monte Carlo method.
SIM.h
#ifndef SIM_H
#define SIM_H
#include <random>
#include "SIM.h"
#include <math.h>
#include <ctime>
#include <iostream>
#include <chrono>
#include <fstream>
#include <string>
using namespace std;
class Sim{
private:
double xCoor, yCoor, resultPyth, inCircle, outsideCircle, approxPi, totalRead;
int runs, totalInsideCircle;
string FILENAME, FILENAME_END;
std::vector<double> piVector;
public:
Sim(){}
explicit Sim(int pRuns);
~Sim() = default;
bool isInCircle();
void calcPiAndPrint();
};
#endif
SIM.cpp
#include "SIM.h"
#include <chrono>
#include <ctime>
#include <fstream>
#include <iostream>
#include <math.h>
#include <stdio.h>
Sim::Sim(int pRuns) {
runs = pRuns;
}
bool Sim::isInCircle() {
std::random_device rd;
std::mt19937 mt(rd());
std::random_device rd1;
std::mt19937 mt1(rd1());
std::uniform_real_distribution<double> dist{-1.0, 1.0};
std::uniform_real_distribution<double> dist1{-1.0, 1.0};
for (int i = 0; i < runs; i++) {
double x = dist(mt);
double y = dist1(mt1);
xCoor = x;
yCoor = y;
resultPyth = sqrt(pow(x, 2) + pow(y, 2));
if (resultPyth <= 1.0) {
totalInsideCircle++;
}
}
return true;
}
void Sim::calcPiAndPrint() {
cout << "Inside circle: " << totalInsideCircle << endl; <-- a 10-digit number
cout << "Runs : " << runs << endl; //<-- a 10-digit number, should be 1000
cout << "Approximation of Pi = " << (totalInsideCircle / runs) * 4 << endl;
}
main.cpp
#include <iostream>
#include <string>
#include "Sim.h"
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <unistd.h>
using namespace std;
using std::cerr;
using std::endl;
int main () {
Sim *sim;
pid_t childPid;
pid_t pids[10];
for(int i = 0; i < 5; i++ ) {
if((pids[i] = fork()) < 0){
perror("failed to fork...");
return 1;
}
else if(pids[i] == 0){
sim= new Sim(1000);
sim->isInCircle();
exit(0);
}
else{
}
}
int n = 10;
int status;
pid_t pid;
while(n > 0){
pid = wait(&status);
sim->calcPiAndPrint();
printf("Child with pid %ld exited with status 0x%x.\n", (long)pid, status);
n--;
}
delete sim;
return 0;
}
Sorry for the amount of code, i shortened it as much as i could.
So to the problem. The integer I'm passing to the constructor when I'm creating the object will be saved in a variable int runs
. In my code I'm setting it to 1000 but when i call calcPiAndPrint()
it will print a 10 digit number instead. Also accessing totalInsideCircle
will lead to EXC_BAD_ACCESS error but it will print a 10 digit number aswell. I normally don't have any problems with initializing variables but i can't figure out what's wrong here. I do suspect that my forks have something to do with the problem. Any help is appreciated.
If I understand correctly, then what you're doing here is the following:
Sim
object, calls the isInCircle()
method, and exits.sim->calcPiAndPrint()
.Note that the parent process never created a Sim
object. The pointer sim
in the parent process is uninitialized, so trying to dereference it, e.g., by calling a method or trying to access members of the object it doesn't point to, will lead to undefined behavior. In this case, that generally means it will try to access invalid or garbage memory and, ideally, blow up so that you can notice your mistake…