EXC_BAD_ACCESS at main method declaration - c++

I'm trying to get some old C++ code up and running. I've gotten it to compile without error, but it immediately segfaults when I run, without entering main. When I use gdb to find out where things are going wrong, I find the following:
(gdb) run
Starting program: /Users/dreens/Documents/OH/extrabuncher2/ParaOHSB
Reading symbols for shared libraries +++. done
Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0x00007fff5636581c
0x000000010000151e in main (argc=1, argv=0x100000ad0) at ParaMainOHSlowerBuncher.cc:13
13 int main(int argc, char *argv[]){
(gdb) backtrace
#0 0x000000010000151e in main (argc=1, argv=0x100000ad0) at ParaMainOHSlowerBuncher.cc:13
(gdb)
Does anyone know what could cause a memory access issue right at the start of the main method?
The code is rather large, but here is the file containing the main method. Could the included .hh and .cc files be a part of the problem? Should I attach them?
Thanks!
David
#include <iostream>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#include "MoleculeEnsemble.hh"
#include "SlowerForceLoadOH32.cc"
#include "SlowerForceLoadOH12.cc"
//#include "SlowerForceLoad3mmBuncher.cc"
#include "SlowerForceLoad4mmBuncher.cc"
using namespace std;
int main(int argc, char *argv[]){
//int main(){
cout << "Ahhhh!" << endl;
/******Parallel Crap********/
/*
int totalnodes = 0;
int mynode = 0;
MPI_Status status;
MPI_Init(&argv,&argc);
MPI_Comm_size(MPI_COMM_WORLD,&totalnodes);
MPI_Comm_rank(MPI_COMM_WORLD,&mynode);
srand(time(NULL)*mynode);
*/
/******Distribution Parameters *******/
long MoleculeNumber = long(5e4);
double Xcenter = 0;
double Ycenter = 0;
double Zcenter = 0;
double DeltaX = 0.0015;
double DeltaY = 0.0015;
double DeltaZ = 0.01;
int FlatX = 1;
int FlatY = 1;
int FlatZ = 1;
double vXcenter = 0;
double vYcenter = 0;
double vZcenter = 406;
double Vcalc = 406;
double vZfinal = 0;
double DeltavX = 2;
double DeltavY = DeltavX;
double DeltavZ = 40;
int FlatvX = 0;
int FlatvY = 0;
int FlatvZ = 0;
int TimeArrayOnly = 0; //Outputs only Time Array
double TimeOffset = 0; //Adds valve-skimmer flight time to ToF array
/*******Overtone Parameters********/
int S = 1; //parameter S=Vz/Vswitch as defined by VDM et al.
int JILAOT = 0; //JILAOT is either 0 or 1, denoting whether or not to use special switching
/*******Hexapole Parameters********/
double VSD = 0.06;
double Voltage = 2000;
double HexRadius = .00268;
double HexStart = .0238;
double HexEnd = .083170;//0.089103;
double HexOn = 1e-6;
double HexOff = 203e-6;//224e-6; 212 for current data; Good = 243e-6 for 408m/s
double DeltaT = 1e-6;
double DeltaTSeqGen = 1e-9; //Need to use smaller time steps for finding the time sequence
double DetectionTime = HexOff; //Use to fake out hex code
double TriggerLatency = 0;//170e-9;
/*******Detection Parameters*******/
double DetectionPosition = double(0.9319);//0.257480; <- for viewing at 31.5 ||||| 0.9428; <-Mag trap(4stages), .9319 <-MagTrap(3Stages)
double IrisWidth = 0.008;//31.5 0.0023 //PostSlower.015;
double LaserRadius = .001;
/*****Bunching Paramaters******/
int BunchNumber = 0;
int NumberUsed = 0;
/*****Timing Variables*********/
time_t start, finish;
time( &start);
/*****Molecule Parameters******/
double mass =double(17*1.672e-27);
/******ToF Detection Arrays and Slowing Parameters *********/
double Phi = double(34.2);
double PhiEB = double(0);
int NumberOfStages = int(142/S); //Use 142 for Big machine
int EBStages = 3; //Larger Add-on stages at end of slower
double BuncherScale = 1;
double Time[int(1e7)];
int ToFSignal32[int(1e7)];
int ToFSignal12[int(1e7)];
double TimeArray[800];
double VExit[800];
double Average32[7];
double Average12[7];
int LOST[200];
/*************Finished ToF Detection Arrays and Slowing Parameters ********/
/******Force Arrays********/
int Xnumber = 111;
int Ynumber = 21;
int Znumber = 21;
int FLength = Xnumber*Ynumber*Znumber;
double AXxDT[FLength];
double AYxDT[FLength];
double AZxDT[FLength];
double AZxDTSeqGen[FLength];
SlowerForceLoadOH32(AZxDT, AYxDT, AXxDT); //Note how Z and X are placed in this function. My matlab code calls the longitudnal dimension X, here it is Z
double DTovermass = DeltaT/mass;
for(int j = 0; j <FLength; j++){
AXxDT[j] = DTovermass*AXxDT[j];
AYxDT[j] = DTovermass*AYxDT[j];
AZxDT[j] = DTovermass*AZxDT[j];
AZxDTSeqGen[j] = DeltaTSeqGen*AZxDT[j]/DeltaT;
}
double AXxDT12[FLength];
double AYxDT12[FLength];
double AZxDT12[FLength];
SlowerForceLoadOH12(AZxDT12, AYxDT12, AXxDT12); //Note how Z and X are placed in this function. My matlab code calls the longitudnal dimension X, here it is Z
for(int j = 0; j <FLength; j++){
AXxDT12[j] = DTovermass*AXxDT12[j];
AYxDT12[j] = DTovermass*AYxDT12[j];
AZxDT12[j] = DTovermass*AZxDT12[j];
}
/********Load Extra Buncher Forces*********/
int XnumberEB = 251;
int YnumberEB = 41;
int ZnumberEB = 41;
int FLengthEB = XnumberEB*YnumberEB*ZnumberEB;
double AXxDTEB[FLengthEB], AYxDTEB[FLengthEB], AZxDTEB[FLengthEB], AZxDTSeqGenEB[FLengthEB];
SlowerForceLoad4mmBuncher(AZxDTEB, AYxDTEB, AXxDTEB);
for(int j = 0; j <FLengthEB; j++)
{
AXxDTEB[j] = DTovermass*AXxDTEB[j]/BuncherScale;
AYxDTEB[j] = DTovermass*AYxDTEB[j]/BuncherScale;
AZxDTEB[j] = DTovermass*AZxDTEB[j]/BuncherScale;
AZxDTSeqGenEB[j] = DeltaTSeqGen*AZxDTEB[j]/(DeltaT*BuncherScale);
}
/********* End All initiliazation ***************************/
/************Beginning Calculation *************************/
//Create Molecule Ensemble
MoleculeEnsemble Alice(MoleculeNumber,Xcenter,Ycenter,Zcenter,DeltaX,DeltaY,DeltaZ,FlatX,FlatY,FlatZ,vXcenter,vYcenter,vZcenter,DeltavX,DeltavY,DeltavZ,FlatvX,FlatvY,FlatvZ);
//MoleculeEnsemble Bob(MoleculeNumber,Xcenter,Ycenter,Zcenter,DeltaX,DeltaY,DeltaZ,FlatX,FlatY,FlatZ,vXcenter,vYcenter,vZcenter,DeltavX,DeltavY,DeltavZ,FlatvX,FlatvY,FlatvZ);
//Generate the Timing Sequence
Alice.TimeArrayGeneratorWithBuncher(Vcalc,Phi,PhiEB,TimeArray,VExit,AZxDTSeqGen,AZxDTSeqGenEB,HexOff,DeltaTSeqGen,BunchNumber,vZfinal,NumberUsed,NumberOfStages,S,EBStages);
/*if(mynode == 0){
cout << "Slowing utilized " << NumberUsed << " stages, yielding a final velocity of " << VExit[NumberUsed] << " m/s." << endl;
cout << endl;
for(int kk = 0; kk < NumberOfStages; kk++){cout << kk << " , " << TimeArray[kk] << " , " << VExit[kk] << endl;}
}*/
/*Alice.MoleculeEnsemble_Averager(Average32);
Bob.MoleculeEnsemble_Averager(Average12);
cout << "Processor: " << mynode << "\t" << sqrt(pow(Average32[3],2)+pow(Average32[4],2)) << ", " << sqrt(pow(Average12[3],2)+pow(Average12[4],2));
cout << " Mean = " << Average32[6] << ", " << Average12[6] << endl << endl << endl;
*/
if(TimeArrayOnly!=1)
{
//Fly the Ensemble through the hexapole
Alice.HexapoleFlightOH(Voltage, HexRadius, HexStart, HexEnd, HexOn, HexOff, DeltaT, double(3/2), DetectionTime);
//Bob.HexapoleFlightOH(Voltage, HexRadius, HexStart, HexEnd, HexOn, HexOff, DeltaT, double(1/2), DetectionTime);
/*
Alice.MoleculeEnsemble_Averager(Average32);
Bob.MoleculeEnsemble_Averager(Average12);
cout << "Processor: " << mynode << "\t" << sqrt(pow(Average32[3],2)+pow(Average32[4],2)) << ", " << sqrt(pow(Average12[3],2)+pow(Average12[4],2));
cout << " Mean = " << Average32[6] << ", " << Average12[6] << endl << endl << endl;
*/
//Fly the Ensemble through the slower
Alice.SlowerFlight(LOST, Time, ToFSignal32, Phi, TimeArray, DeltaT, AXxDT, AYxDT, AZxDT, AXxDTEB, AYxDTEB, AZxDTEB, Xnumber, Ynumber, Znumber, DetectionPosition, IrisWidth, LaserRadius, NumberOfStages, EBStages,S, TriggerLatency);
//Bob.SlowerFlight(LOST, Time, ToFSignal12, Phi, TimeArray, DeltaT, AXxDT12, AYxDT12, AZxDT12, Xnumber, Ynumber, Znumber, DetectionPosition, IrisWidth, LaserRadius, NumberOfStages, EBStages, S, TriggerLatency);
}
/**********Ending Calculation **********************/
//Alice.MoleculeEnsemble_Drawer();
/*
Alice.MoleculeEnsemble_Averager(Average32);
Bob.MoleculeEnsemble_Averager(Average12);
cout << "Processor: " << mynode << "\t" << sqrt(pow(Average32[3],2)+pow(Average32[4],2)) << ", " << sqrt(pow(Average12[3],2)+pow(Average12[4],2));
cout << " Mean = " << Average32[6] << ", " << Average12[6] << endl << endl;
*/
//Output ToF signal
if(TimeArrayOnly!=1)
{
for(int ii = 0; ii < int(1e7); ii++)
{
if(ToFSignal32[ii] > 0 && Time[ii] > 3e-3)
{
cout << Time[ii]+TimeOffset << "," << ToFSignal32[ii] << endl;
//+double(VSD/vZcenter)+38e-6 << "," << ToFSignal32[ii] << endl;
}
if(ToFSignal12[ii] > 0 && Time[ii] > 3e-3)
{
cout << Time[ii]+TimeOffset << "," << ToFSignal12[ii] << endl;
//+double(VSD/vZcenter)+38e-6 << "," << ToFSignal12[ii] << endl;
}
}
}
if(TimeArrayOnly==1)
{
for(int ii = 0; ii < NumberOfStages+EBStages+1; ii++)
{
cout << ii << "\t" << TimeArray[ii] << "\t" << VExit[ii] << endl;
//+double(VSD/vZcenter)+double(265e-6) << "\t" << VExit[ii] << endl;
}
}
/*for(int ii = 0; ii < NumberOfStages; ii++)
{
cout << ii << "\t" << LOST[ii] << endl;
}
*/
/*
MPI_Finalize();
*/
}

You're out of stack space.
You declare very large arrays in your code (over 10 million elements), which are all allocated on the stack. Instead of declaring the arrays statically, use dynamic memory allocation. So, instead of
double Time[int(1e7)];
write
double* Time;
Time = new double[int(1e7)];
and hope to have enough RAM in your computer :)

Related

Heap corrupted and strange breakpoint in Runge Kutta diff eq solver

I'm trying to implement Runga Kutta method for solving the Lorenz differential equation system.
At some point, the program always stops at a breakpoint which I can't see, and then throws an error about heap corruption.
Something must be wrong with the way I use the pointers, but I have no idea what's not working well.
Here's my code:// Runge_Kutta.cpp : This file contains the 'main' function. Program execution begins and ends there.
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <stdlib.h>
#include <iostream>
#include <stdio.h>
#include <fstream>
#include <vector>
#include <time.h>
#include <math.h>
#include <fstream>
#include <chrono>
using namespace std;
const int dimension=3;
double* F = new double(3);
double p1 = 10;
double p2 = 28;
double p3 = 8.0 / 3.0;
double* K1 = new double(3);
double* K2 = new double(3);
double* K3 = new double(3);
double* K4 = new double(3);
double* X = new double(3);
double* t = new double(3);
double a = 0;
double b = 100;
const int N = 1000;
//double * x=new double[N];
double dt = (b - a) / N;
void f(double *F,double *x, double *t)
{
double dx1 = p1 * (x[1] - x[0]);
double dx2 = x[0] * (p2 - x[2]) - x[1];
double dx3 = x[0] * x[1] - p3 * x[2];
//cout << "dx-ek: " << dx1 << " " << dx2 << " " << dx3 << "\n";
F[0] = dx1;
F[1] = dx2;
F[2] = dx3;
}
double* RK4(double* x, double *t, double dt)
{
f(K1, x, t);
//cout << "K1: " << K1[0] << " " << K1[1] << " " << K1[2] << "\n";
for (int i = 0; i < dimension; i++)
{
X[i] = x[i] + dt * K1[i] * 0.5;
}
f(K2, X, t);
//cout << "K2: " << K2[0] << " " << K2[1] << " " << K2[2] << "\n";
for (int i = 0; i < dimension; i++)
{
X[i] = x[i] + dt * K2[i] * 0.5;
}
f(K3, X, t);
//cout << "K3: " << K3[0] << " " << K3[1] << " " << K3[2] << "\n";
for (int i = 0; i < dimension; i++)
{
X[i] = x[i] + dt * K2[i] * 0.5;
}
f(K4, X, t);
//cout << "K4: " << K4[0] << " " << K4[1] << " " << K4[2] << "\n";
for (int i = 0; i < dimension; i++)
{
//cout << "Ennek nem kéne 0-nak lennie: " << K1[i] * 0.1666666 + K2[i] * 0.33333333 + K3[i] * 0.3333333 + K4[i] * 0.1666666 << '\n';
x[i] = x[i] + dt * (K1[i] * 0.1666666 + K2[i] * 0.33333333 + K3[i] * 0.3333333 + K4[i] * 0.1666666);
//cout << "Return előtt előtt: " << x[0] << " " << x[1] << " " << x[2] << "\n";
}
//cout << "Return előtt: " << x[0] << " " << x[1] << " " << x[2] << "\n";
return x;
}
int main()
{
cout << "Let's start!";
std::ofstream myfile;
myfile.open("solution.csv");
double* x = new double(3);
/*
for(int z=0;z<dimension;z++)
{
//cout << "WHat the heck?";
x[z]= 0;
}
*/
x[0] = -5.0;
x[1] = 0.0;
x[2] = 0.0;
auto start=std::chrono::high_resolution_clock::now();
for (int j = 0; j < N; j++)
{
RK4(x, t, dt);
//cout << j << "\n";
//cout << "Return után "<< x[0] << " " <<x[1]<<" "<<x[2]<<" it: "<<j << "\n";
//cout << "\n";
for (int u = 0; u < dimension; u++)
{
myfile << x[u];
if (u <= dimension - 2) myfile << ",";
else myfile << "\n";
}
}
auto elapsed = std::chrono::high_resolution_clock::now()-start;
long long microseconds = std::chrono::duration_cast<std::chrono::microseconds>(elapsed).count();
cout << "Simulation time: " << microseconds << " microsec" << endl << endl;
myfile.close();```

What would be a more efficient way of storing variables?

I am working on a music program that calls notes from the chromatic scale based on intervals. These interval variables (h - half step, w - whole step and wh -whole and a half step) will be used for determining scale incriments (Major = WWHWWWH) and will later be used to measure interval lengths across a vector of strings to potentially output measurements like "3 Whole Steps and a Half Step".
I'm wondering what would be the more efficient way to store the simple variables, as I would eventually like to make a cellphone app out of it and want it to be as easy on the battery/memory as possible. . And I am still learning. Here are my thoughts:
int H = 1;
int W = 2;
int WH = 3;
Int Fiv = 5;
Int Sev = 7;
or
int H = 1;
int W = H+H;
int WH = W + H;
int Fiv = WH+W;
int Sev = Fiv + W;
Int H = 1; int W = H*2; int WH = W+H; etc..
I'm primarily interested in how the differentiation of initialization will effect both memory and performance if at all?
I know I shouldn't have everything in main, but this is a work in progress, and I am obviously new to programming - so please look past the layout .. here is the code it's presently being used in..
#include <algorithm>
#include <iostream>
#include <iterator>
#include <string>
#include <sstream>
#include <vector>
#include <map>
const std::vector<std::string> st_sharps{"C","C#","D","D#","E","F","F#","G","G#","A","A#","B" };
const std::vector<std::string> st_flats{"C","Db","D","Eb","E","F","Gb","G","Ab","A","Bb","B" };
struct steps{ int maj = 0; int min = 0;} step;
constexpr int H = 1;
constexpr int W = 2;
constexpr int Tre = 3;
constexpr int Fif = 5;
constexpr int Sev = 7;
const int size = st_flats.size();
const std::vector<int> Major = { W, W, H, W, W, W, H };
struct circle{
std::stringstream sharp;
std::stringstream flat;
std::stringstream minor;
std::stringstream dimin; };
struct scales{
circle fifths;
std::stringstream maj;
std::stringstream min; } scale;
int main(){
//Circle of Fifths
for (int j = 0; j < size; j++){
int five = j * Sev;
scale.fifths.sharp << st_sharps[five % size] << " ";
scale.fifths.flat << st_flats[five % size] << " ";
scale.fifths.minor << st_sharps[((size - Tre) + five) % size] << " ";
scale.fifths.dimin << st_sharps[((size - H) + five) % size] << " ";
}
std::cout << "Circle of Fifths:\n";
std::cout << "Major >> Relative Minor >> Diminished " << std::endl;
std::cout << "Maj: " << scale.fifths.sharp.str() << std::endl;
std::cout << "Min: " << scale.fifths.minor.str() << std::endl;
std::cout << "Dim: " << scale.fifths.dimin.str() << std::endl;
std::cout << "\nflats: " << scale.fifths.flat.str() << "\n" << std::endl;
//Major and Minor Scales
for (int i = 0; i < Major.size(); i++) {
scale.maj << st_sharps[step.maj] << " ";
scale.min << st_flats[((size - Tre) + step.min) % size] << " ";
step.maj += Major[i];
step.min += Major[(i + Fif) % Major.size()];
}
std::cout << "C Major:\n" << scale.maj.str() << "\n" << std::endl;
std::cout << "A Minor:\n" << scale.min.str() << "\n" << std::endl;
return 0;
}
I'd choose a version that expresses "'W' is the double of 'H'" the best way. My preferred way would therefore be:
constexpr int H = 1;
constexpr int W = 2*H;
constexpr int WH = W+H;
Note that your version int W = H++ is not what you probably intend, since H++ is not equal to H+1; it is actually equal to int W = H; H = H + 1.

Write a function that returns a pointer to the maximum value using pointers c++

This is the problem that I'm trying to solve for class in C++.
Write a function that returns a pointer to the maximum value of an array of floating-point data: double* maximum(double* a, int size). If size is 0, return nullptr.
The issues I'm having are that:
The final output is not the correct location for the maximum value in the array.
An error that says: "cannot convert 'double**' to 'double*' in the initialization".
If I use nullptr at any point in this code, CodeBlocks gives me an error.
#include <iostream>
using namespace std;
// return pointer to location from function
double * maximum(double* a, int size)
{
double maxVal = a[0]; // this is the starting max value
double* max_pos = &a; // points to the value in a[0]
// initialis]ze both variables
for(int i = 0; i < size; i++){
if(a[i] > maxVal){
maxVal = a[i];
cout << max_pos << endl;
max_pos = &a[i];
}
}
// return address
return max_pos;
}
int main()
{
double myarr[5];
int i = 0;
int arrSize = 5;
cout << "Input 5 floating point values for your array" << endl;
for(i = 0; i < arrSize; i++){ // loop to input values
cin >> myarr[i];
}
for(int j = 0; j < arrSize; j++){
cout << "Location for " << myarr[j] << " = " << &myarr[j] << endl;
}
double* maxNum = maximum( myarr, arrSize);
cout << &maxNum << endl;
return 0;
}
This is the output I'm getting after finding max_pos:
The code you showed has a few mistakes in it:
using namespace std; is bad!
you are not following your instructions to return nullptr when size is 0.
you are trying to initialize max_pos (a double*) with &a (a double**), which is a compiler error.
you are passing &maxNum (a double**) to std::cout, printing the address of the maxNum variable itself, not the address that it is pointing to (the found array element). You need to pass maxNum (a double*) if you want to print the address of the found element, or pass *maxNum (a double) if you want to print the value of the found element.
Try something more like this instead:
#include <iostream>
// return pointer to location from function
double* maximum(double *a, int size)
{
if (size == 0) return 0;
// initialize both variables
double* max_pos = a; // points to the value in a[0]
double maxVal = *max_pos; // this is the starting max value
std::cout << "max_pos = " << max_pos << " (" << maxVal << ")" << std::endl;
for(int i = 1; i < size; ++i){
if (a[i] > maxVal){
max_pos = &a[i];
maxVal = *max_pos;
std::cout << "max_pos = " << max_pos << " (" << maxVal << ")" << std::endl;
}
}
// return address
return max_pos;
}
int main()
{
const int arrSize = 5;
double myarr[arrSize];
std::cout << "Input " << arrSize << " floating point values for your array" << std::endl;
for(int i = 0; i < arrSize; ++i) { // loop to input values
std::cin >> myarr[i];
}
for(int j = 0; j < arrSize; ++j) {
std::cout << "Location for " << myarr[j] << " = " << &myarr[j] << std::endl;
}
double* maxNum = maximum(myarr, arrSize);
std::cout << "maxNum = " << maxNum << " (" << *maxNum << ")" << std::endl;
return 0;
}
Live Demo
And then, you can throw it all away and use STL algorithms instead, like std::max_element():
#include <iostream>
#include <algorithm>
#include <iterator>
int main()
{
const int arrSize = 5;
double myarr[arrSize];
std::cout << "Input " << arrSize << " floating point values for your array" << std::endl;
// loop to input values
std::copy_n(std::istream_iterator<double>(std::cin), arrSize, myarr);
for(int i = 0; i < arrSize; ++i) {
std::cout << "Location for " << myarr[i] << " = " << &myarr[i] << std::endl;
}
double *maxNum = std::max_element(myarr, myarr + arrSize);
std::cout << "maxNum = " << maxNum << " (" << *maxNum << ")" << std::endl;
return 0;
}
Live Demo

segmentation fault for string function argument

I have a simple main code that gives me segmentation fault when calling a function. In the following code, I have two functions, the first one works correctly but the program doesn't enter the second one and gives me segmentation fault error. Is there any reason for that? I have made sure about the following:
The variables o and c are not out of bound.
cn is initialized correctly.
I have a read-only access to cm and argv. Plus it does not even enter the function evaluate
Here is the code:
void print_cm(vector<vector<int> > *cm, char* gtf);
void evaluate(vector<vector<int> > *cm, char* gtf);
int main(int argc, char** argv)
{
int o = 2; // It is initialized
int c = 4; // It is initialized
vector<vector<int> > cm; // It is initialized
if (argc>4)
print_cm(&cm, argv[o]);
if (argc>4)
{
cout << argv[c] << endl; // Works
// The following also works
for (int i=0; i<cm.size(); i++)
for (int j=0; j<cm[i].size(); j++)
cout << cm[i][j] << " ";
// The following causes segmentation fault;
evaluate(&cm, argv[c]);
}
return 0;
}
void evaluate(vector<vector<int> > *cm, char* gtf)
{
// Read-only access to cm and gtf
}
void print_cm(vector<vector<int> > *cm, char* gtf)
{
// Read-only access to cm and gtf
}
Here is the complete code:
#include "includes/Utility.h"
#include "includes/Graph.h"
void print_cm(vector<vector<int> > *cores, char* output);
void evaluate(vector<vector<int> > const *cm, char* gtf);
int main(int argc, char** argv)
{
int g = -1, c = -1, o = -1;
for (int i=1; i<argc-1; i++)
if (argv[i][0]=='-')
{
if (argv[i][1]=='g')
g = i + 1;
else if (argv[i][1]=='c')
c = i + 1;
else if (argv[i][1]=='k')
ki = i + 1;
else if (argv[i][1]=='s')
si = i + 1;
else if (argv[i][1]=='o')
o = i + 1;
}
Graph G;
if (c>0) G.read_input(argv[g], argv[c]);
else G.read_input(argv[g]);
if (ki > 0)
{
int k = atoi(argv[ki]);
cout << k << endl;
}
if (si > 0)
{
int s = atoi(argv[si]);
cout << s << endl;
}
// Find communities
vector<vector<int> > cores;
G.partitioning(&cores);
if (o>0)
print_cm(&cores, argv[o]);
if (c>0)
{
cout << "here" << endl;
for (size_t i=0; i<cores.size(); i++)
for (size_t j=0; j<cores[i].size(); j++)
if (cores.at(i).at(j)<0) cout << "here";
cout << "here" << endl;
evaluate(&cores, argv[c]);
}
}
return 0;
}
void print_cm(vector<vector<int> > *cores, char* output)
{
ofstream out;
out.open(output);
for(size_t i=0; i<(*cores).size(); i++)
{
for(size_t j=0; j<(*cores)[i].size(); j++)
out << (*cores)[i][j] << " ";
out << endl;
}
out.close();
return ;
}
void evaluate(vector<vector<int> > const *cm, char* gtf)
{
// we evaluate precision, recall, F1 and F2
vector<vector<int> > gt;
ifstream in;
char str[100000000];
in.open(gtf);
while(in.getline(str, 100000000))
{
stringstream s;
s << str;
int a;
gt.resize(gt.size()+1);
while (s >> a) gt[gt.size()-1].push_back(a);
}
in.close();
cout << "==================== Evaluation Results ====================" << endl;
int imax = 0;
for(size_t i=0; i<(*cm).size(); i++)
imax = max(imax, *max_element((*cm)[i].begin(), (*cm)[i].end()));
for(size_t i=0; i<gt.size(); i++)
imax = max(imax, *max_element(gt[i].begin(), gt[i].end()));
vector<bool> flag(imax, false);
vector<double> recall((*cm).size(), 0), precision((*cm).size(), 0), f1((*cm).size(), 0), f2((*cm).size(), 0);
int overlap;
double size = 0;
for(size_t i=0; i<(*cm).size(); i++)
{
// evaluate
size += (double) (*cm)[i].size();
for(size_t j=0; j<(*cm)[i].size(); j++)
flag[(*cm)[i][j]] = true;
double p, r, ff1, ff2;
for(size_t j=0; j<gt.size(); j++)
{
overlap = 0;
for(size_t k=0; k<gt[j].size(); k++)
if (flag[gt[j][k]]) overlap++;
p = (double) overlap / (double) (*cm)[i].size();
if (p > precision[i])
precision[i] = p;
r = (double) overlap / (double) gt[j].size();
if (r > recall[i])
recall[i] = r;
ff1 = (double) 2*(p*r)/(p+r);
if (ff1 > f1[i])
f1[i] = ff1;
ff2 = (double) 5*(p*r)/(4*p + r);
if (ff2 > f2[i])
f2[i] = ff2;
}
for(size_t j=0; j<(*cm)[i].size(); j++)
flag[(*cm)[i][j]] = false;
}
double Recall = 0, Precision = 0, F1 = 0, F2 = 0;
for(size_t i=0; i<(*cm).size(); i++)
{
Recall += recall[i];
Precision += precision[i];
F1 += f1[i];
F2 += f2[i];
}
cout << "+--------------+--------------+--------------+--------------+" << endl;
cout << "| " << setiosflags( ios::left ) << setw(10) << "Precision";
cout << " | " << setiosflags( ios::left ) << setw(10) << "Recall";
cout << " | " << setiosflags( ios::left ) << setw(10) << "F1-measure";
cout << " | " << setiosflags( ios::left ) << setw(10) << "F2-measure";
cout << " |" << endl;
cout << "| " << setiosflags( ios::left ) << setw(10) << Precision/(*cm).size() ;
cout << " | " << setiosflags( ios::left ) << setw(10) << Recall/(*cm).size();
cout << " | " << setiosflags( ios::left ) << setw(10) << F1/(*cm).size();
cout << " | " << setiosflags( ios::left ) << setw(10) << F2/(*cm).size();
cout << " |" << endl;
cout << "+--------------+--------------+--------------+--------------+" << endl;
cout << "Number of communities: " << (*cm).size() << endl;
cout << "Average community size: " << size/(*cm).size() << endl;
return ;
}
char str[100000000];
This is in your evaluate function. This are 100 million bytes, or about 95 MB that you're allocating on the stack.
Typical stack sizes are far less than that, around 1 MB.
So apart from possible other problems this is most likely causing a stack overflow.
When entering the function, the stack frame gets extended to be large enough to hold the local variables. As soon as the stack is used then (to write a default value) you're accessing invalid (non stack, thankfully protected) memory.

Basic Matrix multiplication with pthreads c++ error

I have a matrix multiplication code that I am supposed to process in parallel. I have a code here that I believe should work but does not. It either causes segmentation faults or gives me all gibberish values. Can any one help? Thanks in advance.
//*******************STRUCTS AND GLOBAL VARIABLES*****************************//
struct Matrix
{
int d[SIZE][SIZE];
};
Matrix* matrix_addr[SIZE]; // array to store the address of the matrices
int n;
int m;
pthread_mutex_t my_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t my_cond = PTHREAD_COND_INITIALIZER;
//****************************THREAD******************************************//
void* calcTerm(void* arg)
{
pthread_mutex_lock(&my_mutex);
int sum = 0;
Matrix* m0 = (Matrix*) arg;
Matrix* m1 = (Matrix*) ((int*)arg + 1);
Matrix* m2 = (Matrix*) ((int*)arg + 2);
cout << endl << "Print\n" << endl;
print (m0);
for (int i = 0; i < SIZE; ++i)
{
cout << "\ni = " << i << "\tn = " << m1->d[n][i] << "\tm = " << m2->d[i][m] << endl;
sum = sum + (m1->d[n][i] * m2->d[i][m]);
}
cout << endl << endl << sum << endl;
m0->d[n][m] = sum;
pthread_mutex_unlock(&my_mutex);
cout << endl << "Going out of thread\n" ;
pthread_exit(NULL);
}
//********************************MAIN****************************************//
int main()
{
Matrix m0, m1, m2; //Matrices are 3x3;
// m0 <= m1 * m2
pthread_t id[9]; // 3x3 matrix multiplication requires 9 threads.
matrix_addr[0] = &m0; // the pointers to the matrices are stored here.
matrix_addr[1] = &m1;
matrix_addr[2] = &m2;
n = m = 0; // initialize the global variable
srand(time(NULL)); // seed rand()
for (int i = 0; i < SIZE; i++)
{
for (int j = 0; j < SIZE; j++)
{
m0.d[i][j] = 0; // m0 is being cleared for the output
m1.d[i][j] = rand()%10; // m1 and m2 are generated with rand()
m2.d[i][j] = rand()%10;
}
}
//display the input matrices
cout << "MATRIX 1:\n\n";
print (&m1);
cout << "\nMATRIX 2:\n\n";
print (&m2);
cout << "\nMATRIX 3:\n\n";
print (&m0);
for (int i = 0; i < SIZE*SIZE; i++) // run all the threads for calculating each output
{
m = i % SIZE;
n = i / SIZE;
cout << endl << "Going in to thread " << i << " with n = " << n << " and m = " << m;
pthread_create(&id[i], NULL, calcTerm, (void*) matrix_addr);
cout << endl << "Out of thread " << i ;
//pthread_join(id[i], NULL);
}
//pthread_cond_wait(&my_cond, &my_mutex);
cout << endl << endl;
print_result (&m0, &m1, &m2);
return 0;
}
It seems like the calcTerm thread does not take the correct pointers or something. It calculates gibberish values, but the final output at the end of main prints the same matrices I started off with.
Thanks again.