Целочисленная инициализация C ++ в заголовке - PullRequest
0 голосов
/ 16 сентября 2018

Я столкнулся с проблемой, которую на самом деле не понимаю. Я запускаю этот код в QTcreator в Lubuntu, и проблема, которую я имею, объясняется после кода. Это простая программа, которая запускает несколько процессов с использованием вилок, которые аппроксимируют Пи методом Монте-Карло.

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;
}

Извините за количество кода, я сократил его настолько, насколько смог. Так что к проблеме. Целое число, которое я передаю конструктору при создании объекта, будет сохранено в переменной int runs. В моем коде я установил его на 1000, но когда я позвоню calcPiAndPrint(), вместо этого он напечатает 10-значный номер. Кроме того, доступ к totalInsideCircle приведет к ошибке EXC_BAD_ACCESS, но также напечатает 10-значный номер. У меня обычно нет проблем с инициализацией переменных, но я не могу понять, что здесь не так. Я подозреваю, что мои вилки как-то связаны с этой проблемой. Любая помощь приветствуется.

1 Ответ

0 голосов
/ 16 сентября 2018

Если я правильно понимаю, то, что вы здесь делаете, это следующее:

  1. Вы разбиваете ток на 5 новых процессов.
  2. Каждый из этих дочерних процессов создаетnew Sim object вызывает метод isInCircle() и завершается.
  3. Родительский процесс вызывает sim->calcPiAndPrint().

Обратите внимание, что родительский процесс никогда не создавал Simобъект.Указатель sim в родительском процессе неинициализирован, поэтому попытка разыменования его, например, путем вызова метода или доступа к членам объекта, на который он не указывает, приведет к неопределенному поведению.В этом случае это обычно означает, что он попытается получить доступ к недействительной или мусорной памяти и, в идеале, взорваться, чтобы вы могли заметить свою ошибку ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...