Creating Multiple Threads in For Loop to Process 2d Array - c++

Ok so my code is probably a little messy - I'm new to this, so sorry in advance! Basically the code reads a file in to a 2d array and then creates multiple threads to perform calculations on each value in a number of rows of the array. The problem I'm having with this is the for loop at the bottom. It runs but does not loop. I have no idea why and have tried a number of things but I'm new to this so honestly have no idea. All the code is below and any help would be greatly, amazingly appreciated!!
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <stdlib.h>
#include <time.h>
#include <pthread.h>
int threadArray[10][10];
int arrayVar[2];
using namespace std;
void *calc(void *arg){
int startPoint = arrayVar[0];
int endPoint = arrayVar[1];
int newArray[10][10];
int calculated;
for (int i = startPoint ; i < endPoint; i++){
for (int j = 0; j < 10; j++){
calculated = (threadArray[i][j] * 2 + 4) * 2 + 4;
newArray[i][j] = calculated;
}
}
for (int i = startPoint; i < endPoint; i++){
for (int j = 0; j < 10; j++){
cout << newArray[i][j] << " ";
}
cout << endl;
}
return NULL;
}
int main(){
int rc;
int start = 0;
int end;
ifstream numFile;
numFile.open("numbers.txt");
if (numFile.is_open()){
for (int row = 0; row < 10; row++){
std::string line;
std::getline(numFile, line);
std::stringstream iss(line);
for (int col = 0; col < 10; col++){
std::string num;
std::getline(iss, num, ' ');
std::stringstream converter(num);
converter >> threadArray[row][col];
}
}
cout << "Original 2D Array" << endl << endl;
for (int i = 0; i < 10; i++){
for (int j = 0; j < 10; j++){
cout << threadArray[i][j] << " ";
}
cout << endl;
}
cout << endl;
}
srand (time(NULL) );
const int rowArray[3] = {1, 2, 5};
int arrayIndex = rand() % 3;
int noOfRows = (rowArray[arrayIndex]);
end = noOfRows;
int noOfThreads = 10 / noOfRows;
pthread_t threads[noOfThreads];
arrayVar[2];
cout << "2D Array Altered" << endl << endl;
for (int t = 0; t < noOfThreads; t++){
arrayVar[0] = start;
arrayVar[1] = end;
rc = pthread_create(&threads[t], NULL, calc, NULL);
start = start + noOfRows;
end = end + noOfRows;
pthread_exit(NULL);
}
}

for (int t = 0; t < noOfThreads; t++)
{
arrayVar[0] = start;
arrayVar[1] = end;
rc = pthread_create(&threads[t], NULL, calc, NULL);
start = start + noOfRows;
end = end + noOfRows;
// pthread_exit(NULL); <-- this EXITS the loop and main
}
Comment out the above pthread_exit and have a second loop
for (int t = 0; t < noOfThreads; t++)
{
rc = pthread_join(threads[t], NULL);
}
pthread_exit(NULL);

Related

How to swap 2d array columns in places?

How would I swap 2d array columns in places, but the swap has to happen between the columns that contain the smallest and biggest element in the 2d array. Any help on this would be appreciated.
#include <iostream>
#include <ctime>
#include <cstdlib>
#define rows 4
#define cols 4
using namespace std;
int main () {
srand(time(0));
int i=0, j=0,n,low,high,lowpos,highpos,a,b;
int arr[rows][cols];
for (i=0; i<rows; i++)
for (j=0; j<cols; j++)
arr[i][j] = 1 + (rand() % 200);
cout << "Random 2d generated array:" << endl;
for (i=0; i<rows; i++){
for (j=0; j<cols; j++)
cout << arr[i][j] << " ";
cout << endl;
}
high=arr[0][0];
low=arr[0][0];
for(i=0;i<rows;++i)
{
for(j=0;j<cols;++j)
{
if(arr[i][j]>high)
high=arr[i][j];
else if(arr[i][j]<low)
low=arr[i][j];
}
}
cout<<"\nBiggest element:"<<high<<"\nSmallest:"<<low<<"\n";
}
I decided to stay in c++11 standard. Of course swap helps do the trick.
#include <cstdlib>
#include <iostream>
#include <iomanip>
#define rows 4
#define cols 4
using Arr = int[rows][cols];
std::pair<int, int> high_low_ids(const Arr arr, int nrow = rows, int ncol = cols) {
int highpos = 0, lowpos = 0;
int high = arr[0][0];
int low = arr[0][0];
for(int i = 0; i < nrow; ++i)
for(int j = 0; j < ncol; ++j)
if(arr[i][j] > high) {
highpos = j;
high=arr[i][j];
}
else if(arr[i][j] < low) {
lowpos = j;
low=arr[i][j];
}
std::cout << "\nBiggest element:" <<high<< "\nSmallest:" << low << "\n";
return {highpos, lowpos};
}
void rows_swap(Arr table2d, int nrow = rows){
auto p = high_low_ids(table2d);
const int high_idx = p.first;
const int low_idx = p.second;
if (high_idx == low_idx)
return;
for (int i = 0; i < nrow; ++i) {
std::swap(table2d[i][high_idx], table2d[i][low_idx]);
}
}
void print_arr(Arr arr, int nrow = rows, int ncol = cols) {
for (int i = 0; i < nrow; i++) {
for (int j = 0; j < ncol; j++)
std::cout << std::left << std::setw(6) << arr[i][j];
std::cout << std::endl;
}
}
int main () {
srand(time(0));
Arr arr;
for (int i = 0; i < rows; ++i)
for (int j=0; j<cols; ++j)
arr[i][j] = 1 + (rand() % 200);
std::cout << "Random 2d generated array:\n";
print_arr(arr);
rows_swap(arr);
std::cout << "Swapped array:\n";
print_arr(arr);
return 0;
}
PS. please avoid using namespace std.

Using pointer Notation to print an array

I would like to point out some random integers using the regular print function, then print again the same integers using pointer notation. When I use pointer notation I run into some trouble. If anyone could send some tips it'd be much appreciated. If i comment out a specific line of code, the program will compile completely, but not with the outputs I'd like.
#include <iostream>
#include <ctime>
#include <stdlib.h> //srand(), rand()
using namespace std;
void printArray(int[], int);
//void printToday(int , );
int main()
{
int i = 0;
const int SZ = 100;
int myArray[SZ] ={0};
srand(time(0));
int myArrayTotal = 0;
int *thelight;
thelight = myArray;
for (int i = 0; i <=100; i++)
{
myArray[i]= i+rand()%1000 ;
}
cout << "Array Notation:\n\n";
printArray(myArray, SZ);
system("pause");
system("cls");
cout << "Pointer Notation: \n\n";
int k = 0;
for (int i = 0; i < 10; ++i)
{
for (int j = 0; j < 10; ++j)
{
cout<< *(thelight + k)<< "\t";
++k; //if I comment out this line the second part of the program will run, but it isn' the values I want.
} cout<< endl;
}
}
void printArray(int ArrayName[], int ArraySize)
{
int k = 0;
for (int i = 0; i < 10; ++i)
{
for(int j = 0; j < 10 ; ++j)
{
cout << ArrayName[k] << "\t";
++k;
}cout << endl;
}
}
Thank you

Pointers Error, break in delete[] pointers [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I'm new to C++ and i have a problem during the compilation of this code. I'm traslating it from another lenguage so i'm having doubts about how pointers works. I think that the error can be made by initializzation of pointers during the loop.
Anyway the aim of the code is: store the variable results and print it out after simulated data is elaborated. My data change size every loop so I've initialized arrays inside of the loop.
using namespace std;
int* Mwa(double price[], string data[], const int period, const int size)
{
double bandup;
double banddw;
int *index;
index = new int[size];
for(int i = 0; i < size; i++)
index[i]=1;
double cmP = size/period;
double cmp = floor(cmP);
double m;
double std;
for(int i = 0; i < period; i++)
{
m = 0;
std = 0;
for(int j = i*cmp; j < (i+1)*cmp - 1; j++)
{
m += price[j];
}
m = m/cmp;
for(int j = i*cmp; j < (i+1)*cmp - 1; j++)
{
std += pow(price[j] - m,2);
}
std = pow(std/cmp, 0.5);
bandup = m + NormalCDFInv(.95)*std; // aggiungere Z value in qlc modo
banddw = m - NormalCDFInv(.95)*std; // aggiungere Z value in qlc modo
for(int j = i*cmp; j < (i+1)*cmp - 1; j++)
{
if(price[j]> bandup)
index[j] = 0;
else if(price[j]< banddw)
index[j] = 0;
else
index[j] = 1;
}
}
return index;
}
///////////////////////////////////////////////////// MAIN /////////////////////////////////////////////////////////////////////
void main()
{
const int bdays = 251;
std::string f;
cout << "Insert the path of Real Dates to be used \n";
std::cin >> f;
if(f.size() < 5)
f = "H:/Bid-Ask/C++/Bid-Ask Project/Bid-Ask Project/DateReali.txt";
cout << "Insert the path of GTR Input Data to be used \n";
std::string path;
std::cin >> path;
if(path.size() < 5)
path = "H:/Bid-Ask/";
cout << "Insert an Integer number of simulations \n";
int sim;
std::cin >> sim;
double T = 1;
int dayC = 252;
double dt = T/dayC;
int expiry[15] = {1,2,3,4,5,6,7,8,9,10,12,15,20,30,50};
std::string name = " y.csv";
int period = 15;
const double sigmaeps = 0.051;
const double sigmaeta = 0.091;
double **results;
results = new double*[sim];
for(int i =0; i < 15; i++)
results[i] = new double[sim];
double *param;
for(int rnd = 0; rnd < sim; rnd++)
{
for(int e = 0; e < period; e++)
{
stringstream ss;
ss << expiry[e];
string exp = ss.str();
string line;
std::ifstream filein;
filein.open ((path) + exp + name);
if(filein.fail())
{
std::cout << "File opening error" << std::endl;
}
else
{
double *cleanprice;
string *cleandata;
string *cleantime;
int *price2;
double *series;
double *ret;
double *price;
string *data;
string *time;
int count = 0;
while(getline(filein,line))
{
count++;
}
filein.close();
int c = count-1;
data = new string[c];
time = new string[c];
price = new double[c];
cout << exp + "\t" << count << "\n";
filein.open (path + exp + name);
for(int i = 0; i<count; i++)
{
int cols;
if(i==0)
cols = 49;
else
cols = 47;
for(int j=0; j < cols; j++)
{
getline(filein,line,',');
if(i == 0)
continue;
if(j==2)
{
data[i-1] = line.substr(1,10);
time[i-1] = line.substr(12,8);
//cout << data[i-1] + "\t";
}
else if(j == 20)
{
std::istringstream stm;
stm.str(line.substr(1,line.length()));
stm >> price[i-1];
//price[i-1] = atof((line.substr(2,line.length())).c_str());
//cout << price[i-1] << "\n";
}
else
continue;
}
}
filein.close();
price2 = Mwa(price, data, period, c);
int newc = cumsumC(price2,c);
cleantime = new string[newc];
cleanprice = new double[newc];
cleandata = new string[newc];
int Ix = 0;
for(int i=0; i<c; i++)
{
if(price2[i] == 1)
{
cleanprice[Ix]=price[i];
cleantime[Ix] = time[i];
cleandata[Ix] = data[i];
Ix++;
}
}
//for(int i = 0; i < newc; i++)
//cout << cleanprice[i] << "\t" << cleandata[i] << "\t" << cleantime[i] << "\n";
ret = SimpleReturns(cleanprice, cleandata, cleantime, newc);
std::ofstream file;
file.open( f + "/Ret.txt",std::ios::out ) ;
for(int i = 0; i < newc; i++)
file << ret[i] << "\t" << cleanprice[i] << "\t" << cleandata[i] << std::endl;
file.close();
series = KalmanFiltering(f, sigmaeps, sigmaeta, ret, cleandata, newc);
std::ofstream file1;
file1.open(f + "/Kalman.txt",std::ios::out) ;
for(int i = 0; i < bdays; i++)
file1 << series[i] << "\n";
file1.close();
param = MA1(series, bdays);
double bps = pow(abs(param[0]),.5)*param[1]*100;
cout << param[0] << "\t" << param[1] << "\t" << bps << "\r\n";
results[e][rnd] = bps;
delete[] cleantime;
delete[] cleanprice;
delete[] cleandata;
delete[] time;
delete[] data;
delete[] price;
delete[] price2;
delete[] series;
delete[] ret;
}// Else in file reading
}// loop over expiries
}// loop over simulation
std::ofstream fileR;
fileR.open( path + "Results.txt", std::ios::out);
if(fileR.fail())
{
std::cout << "File opening error" << std::endl;
}
else
{
fileR << "Expiry" << endl;
for(int e = 0; e < 15; e++)
{
stringstream ss;
ss << expiry[e];
string exp = ss.str();
fileR << exp << " y" << "\t";
for(int rnd = 0; rnd < sim; rnd++)
{
fileR << results[e][rnd] << "\t";
}
fileR << endl;
}
}
fileR.close();
for(int i =0; i < 15; i++)
delete[] results[i];
delete[] param;
}
double* MA1(double ret[], const int sizeEr)
{
double *Param = new double[1];
int gran = 100;
double* grid;
double* gridV;
grid = new double[gran]; grid[0] = -1;
gridV = new double[gran]; gridV[0] = 0;
for(int i = 1; i < gran; i++)
{
grid[i] = grid[i-1]+.02;
gridV[i] = gridV[i-1]+ .005;
//cout << grid[i] << "\n";
}
double **F;
F = new double*[gran];
for(int i = 0; i < gran; i++)
F[i]= new double[gran];
for(int a = 0; a < gran; a++)
{
double GhostTerm = 0.0;
for(int i = 2; i< sizeEr; i++)
{
double c = 0;
for(int g = 0; g < i-1; g++)
c += pow((-grid[a]),g)*(ret[i-g]);
GhostTerm += pow(c,2);
}
for(int v = 0; v < gran; v++)
{
F[a][v] = -(sizeEr-1)*.5 *log(2*3.14159*pow(grid[v],2)) + (-.5)*GhostTerm/pow(grid[v],2);
}// loop on vola
}// loop on beta
double m = -gran;
int posB = 1;
int posV = 1;
for(int i = 1; i < gran; i++)
{ for(int j = 1; j < gran; j++)
{
if(abs(grid[i]) < .01)
continue;
else
{
m = max(F[i][j],m);
if(F[i][j] == m)
{
posB = i;
posV = j;
}
}
}
}
Param[0] = grid[posB];
Param[1] = gridV[posV];
delete[] F;
delete[] grid;
return Param;
}
#endif __MA1_H_INCLUDED__
#ifndef __KALMANFILTERING_H_INCLUDED__
#define __KALMANFILTERING_H_INCLUDED__
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#include "MyLib.h"
#include <array>
using namespace std;
double* KalmanFiltering(std::string path, const double sigmaeps, const double sigmaeta, double ret[], string data[], int size)
{
//srand (time(NULL));
string *Realdata;
double *Sim;
std::ifstream filein;
filein.open (path);
int count = 0;
double *a;
double *P;
if(filein.fail())
{
std::cout << "File opening error" << std::endl;
return 0;
}
else
{
string line;
while(getline(filein,line))
{
count++;
}
filein.close();
Sim = new double[count];
Realdata = new string[count];
filein.open(path);
for(int i = 0; i<count; i++)
{
getline(filein,line);
Realdata[i] = line;
//cout << Realdata[i];
}
}
filein.close();
a = new double[count];
P = new double[count];
a[0]= mean(ret, size);
P[0]= variance(ret, size);
int *idx;
idx = new int[size];
for(int i=0; i < count;i++)
{
const char *chrR = Realdata[i].c_str();
double GhostR= 0.0;
for(int j=0; j < size; j++)
{
const char *chrD = data[j].c_str();
if(strcmp(chrR, chrD)== 0)
{
idx[j] = 1.0;
GhostR += ret[j];
}
else
idx[j] = 0.0;
}
if(cumsumC(idx,size) != 0)
{
double v = GhostR/cumsumC(idx,size) - a[i];
double F = P[i] + sigmaeps*sigmaeps;
a[i+1] = a[i]+(P[i]/F)*v;
P[i+1] = P[i]*(1- P[i]/F) + sigmaeta*sigmaeta;
}
else
{
a[i+1]= a[i];
P[i+1]= P[i] + sigmaeta*sigmaeta;
}
}// Loop over real data
for(int i=0; i < count;i++)
{
double GhostR = 0;
int counter = 0;
const char *chrR = Realdata[i].c_str();
for(int j=0; j < size; j++)
{
if(strcmp(chrR,data[j].c_str())== 0)
{
idx[j] = 1.0;
counter++;
GhostR += ret[j];
}
else
idx[j] = 0;
}
if(cumsumC(idx,size) != 0)
{
Sim[i] = GhostR/counter;
}
else
{
double s = rand() % 9999 + 1;
Sim[i] = a[i] + pow(P[i],2)*NormalCDFInv(s/10000);
}
}// Loop over Simulation
delete[] idx;
//delete[] a;
//delete[] P;
delete[] Realdata;
return Sim;
}// Kalman End
#endif _KALMANFILTERING_H_INCLUDED_
You do not need to use arrays for this. C++ has a nice std::vector class which requires no deletion, or manual memory management, do use it:
http://www.cplusplus.com/reference/vector/vector/
double *price;
string *data;
data = new string[c];
price = new double[c];
can be written as:
std::vector<double> price;
std::vector<std::string> data;
data.reserve(c);
price.reserve(c);
and you do not worry about allocation/deallocation of funny memory blocks.

Creating threads to do calculations on array - does not seem to access array correctly

Ok so I'm passing an argument to a thread that I use to tell it where to look in an array. I've got rid of the segmentation fault that was previously being thrown but it's still not working as I'd like. The int passed in pointer seems to change somewhere along the way. This throws the whole array out and I'm getting really random numbers in it. If there is any possible way anyone can help me sort this it'd be greatly appreciated. All I want the code to do is to read through a 2d array, select a random number (1, 2 or 5) to decide how many rows of the array will be processed by a thread and then create a number of threads to process the rows of the array. This could be the wrong way to go about it but I have no idea how else to do it. It's supposed to be class work to help me understand threads etc but so far I think it's just confusing me even more! Please help if you can!
int threadArray[10][10];
int arrayVar[10][2];
using namespace std;
void *calc(void *pointer){
int *point, pointerA;
point = (int *) pointer;
pointerA = *point;
int startPoint = arrayVar[pointerA][0];
int endPoint = arrayVar[pointerA][1];
int newArray[10][10];
int calculated;
for (int i = startPoint ; i < endPoint; i++){
for (int j = 0; j < 10; j++){
calculated = (threadArray[i][j] * 2 + 4) * 2 + 4;
newArray[i][j] = calculated;
}
}
for (int i = startPoint; i < endPoint; i++){
for (int j = 0; j < 10; j++){
cout << newArray[i][j] << " ";
}
cout << endl;
}
return 0;
}
int main(){
int rc;
int start = 0;
int end;
ifstream numFile;
numFile.open("numbers.txt");
if (numFile.is_open()){
for (int row = 0; row < 10; row++){
std::string line;
std::getline(numFile, line);
std::stringstream iss(line);
for (int col = 0; col < 10; col++){
std::string num;
std::getline(iss, num, ' ');
std::stringstream converter(num);
converter >> threadArray[row][col];
}
}
cout << "Original 2D Array" << endl << endl;
for (int i = 0; i < 10; i++){
for (int j = 0; j < 10; j++){
cout << threadArray[i][j] << " ";
}
cout << endl;
}
cout << endl;
}
srand (time(NULL));
const int rowArray[3] = {1, 2, 5};
int arrayIndex = rand() % 3;
int noOfRows = (rowArray[arrayIndex]);
end = noOfRows;
int noOfThreads = 10 / noOfRows;
pthread_t threads[noOfThreads];
arrayVar[noOfThreads][2];
start = 0;
end = noOfRows;
for (int a = 0; a < noOfThreads; a++){
arrayVar[a][0] = start;
arrayVar[a][1] = end;
start = start + noOfRows + 1;
end = end + noOfRows + 1;
}
int *pointer = 0;
cout << "2D Array Altered" << endl << endl;
for (int t = 0; t < noOfThreads; t++){
pointer = (int *) t;
rc = pthread_create(&threads[t], NULL, calc, &pointer);
}
for (int t = 0; t < noOfThreads; t++){
rc = pthread_join(threads[t], NULL);
}
pthread_exit(NULL);
}
Here's your problem:
for (int t = 0; t < noOfThreads; t++) {
pointer = (int *) t;
rc = pthread_create(&threads[t], NULL, calc, &pointer);
}
You are passing a pointer to pointer to pthread_create, and immediately destroying it when it goes out of scope at the end of the loop body. When the created thread starts running and dereferences that pointer, undefined behavior ensues.
You need to either eat some gray-area behavior and encode your integer in the void* argument to pthread_create:
void *calc(void *pointer) {
int t = reinterpret_cast<int>(pointer);
// ...
}
// snip
for (int t = 0; t < noOfThreads; t++) {
rc = pthread_create(&threads[t], NULL, calc, reinterpret_cast<void*>(t));
}
or dynamically allocate storage to pass an integer to the thread function.

Joining threads in a loop - Conversion error

So I'm trying to join threads in a for loop but it's giving me the error:
invalid conversion from 'pthread_t* {aka long unsigned int*}' to
'pthread_t {aka long unsigned int}'.
The codes are as below and any help would be greatly appreciated!
Thanks in advance!
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <stdlib.h>
#include <time.h>
#include <pthread.h>
int threadArray[10][10];
int arrayVar[2];
using namespace std;
void *calc(void *arg){
int startPoint = arrayVar[0];
int endPoint = arrayVar[1];
int newArray[10][10];
int calculated;
for (int i = startPoint ; i < endPoint; i++){
for (int j = 0; j < 10; j++){
calculated = (threadArray[i][j] * 2 + 4) * 2 + 4;
newArray[i][j] = calculated;
}
}
for (int i = startPoint; i < endPoint; i++){
for (int j = 0; j < 10; j++){
cout << newArray[i][j] << " ";
}
cout << endl;
}
return NULL;
}
int main(){
int rc;
int start = 0;
int end;
ifstream numFile;
numFile.open("numbers.txt");
if (numFile.is_open()){
for (int row = 0; row < 10; row++){
std::string line;
std::getline(numFile, line);
std::stringstream iss(line);
for (int col = 0; col < 10; col++){
std::string num;
std::getline(iss, num, ' ');
std::stringstream converter(num);
converter >> threadArray[row][col];
}
}
cout << "Original 2D Array" << endl << endl;
for (int i = 0; i < 10; i++){
for (int j = 0; j < 10; j++){
cout << threadArray[i][j] << " ";
}
cout << endl;
}
cout << endl;
}
srand (time(NULL) );
const int rowArray[3] = {1, 2, 5};
int arrayIndex = rand() % 3;
int noOfRows = (rowArray[arrayIndex]);
end = noOfRows;
int noOfThreads = 10 / noOfRows;
pthread_t threads[noOfThreads];
arrayVar[2];
cout << "2D Array Altered" << endl << endl;
for (int t = 0; t < noOfThreads; t++){
arrayVar[0] = start;
arrayVar[1] = end;
rc = pthread_create(&threads[t], NULL, calc, NULL);
start = start + noOfRows;
end = end + noOfRows;
}
for (int t = 0; t < noOfThreads; t++){
rc = pthread_join(&threads[t], NULL);
}
pthread_exit(NULL);
}
I think threads[t] is actually just it's pid, it's an integer and you should pass in by value
pthread_join(threads[t], NULL)