c++ pthread join sometimes doesn't work - c++

I'm trying to use pthread in c++.
I write a mergesort with pthread, but sometimes in pthread_join my code has segmentation fault. ( see codes debug info )
for example, for input:
4
5 1 2 3
output is:
** size is more than 2 **
I'm alive!
create 1: 0
create 2: 0
After creating!
i want to exit ... 2 1
i want to exit ... 2 2
join 1: 0
Segmentation fault
when it want to join pthead number 2, segmentation fault occurs.
Thanks in advance!
#include<iostream>
#include<fstream>
#include<cstdlib>
#include<pthread.h>
using namespace std;
struct toSort
{
int size;
int * arr;
toSort(int _size = 0, int * _arr = NULL)
{
size = _size;
arr = _arr;
}
};
void * mergeSort(void *args)
{
toSort * m = static_cast<toSort*>(args);
if(m -> size == 1)
{
pthread_exit(NULL);
}
else if(m -> size == 2)
{
if(*(m -> arr) > *((m -> arr) + 1))
{
int temp = *(m -> arr);
* (m -> arr) = *((m -> arr) + 1);
* ((m -> arr) + 1) = temp;
}
}
else
{
cerr << "** size is more than 2 **" << endl;
int ind = (m -> size) / 2;
pthread_t t1, t2;
toSort *m1, *m2;
m1 = new toSort(ind, (m -> arr));
m2 = new toSort((m -> size) - ind, ((m -> arr) + ind));
cerr << "I'm alive!" << endl;
cerr << "create 1: " << pthread_create( &t1, NULL, &mergeSort, static_cast<void*>(m1)) << endl;
cerr << "create 2: " << pthread_create( &t1, NULL, &mergeSort, static_cast<void*>(m2)) << endl;
cerr << "After creating!" << endl;
cerr << "join 1: " << pthread_join(t1, NULL) << endl;
cerr << "join 2: " << pthread_join(t2, NULL) << endl;
cerr << "After join!" << endl;
// merge(m -> arr, ind, m -> size);
}
cout << "i want to exit ... " << (m -> size) << " " << (*(m -> arr)) << endl;
pthread_exit(NULL);
return 0;
}
int main()
{
int n, arr[100];
// Read
cin >> n;
for(int i = 0; i < n; i++)
cin >> arr[i];
// Solve
toSort * ans = new toSort(n, arr);
pthread_t getAns;
pthread_create( &getAns, NULL, &mergeSort, static_cast<void*>(ans));
pthread_join(getAns, NULL);
// Write
for(int i = 0; i < n; i++)
cout << arr[i] << " ";
cout << endl;
return 0;
}

You have a typo
cerr << "create 2: " << pthread_create( &t1, NULL, &mergeSort, static_cast<void*>(m2)) << endl;
You should be using t2 instead of t1 for the second thread.

Related

Quicksort not sorting one element in the list of strings

Could anyone tell me what is wrong with my code:
int Partition(vector<string>& userIDs, int i, int k) {
int pivot = (i + (k - i) / 2);
string temp;
while(i<k) {
cout << "pivot:" << pivot << endl;
while (userIDs.at(i).compare(userIDs.at(pivot))<0) {
cout << "1. i:"<<i<<" UserIDs.at(i):" << userIDs.at(i) << " UserID.at(pivot): " << userIDs.at(pivot) << endl;
i += 1;
}
while (userIDs.at(pivot).compare(userIDs.at(k))<0) {
cout << "2. k:" << k << " UserIDs.at(k):" << userIDs.at(k) << " UserID.at(pivot): " << userIDs.at(pivot) << endl;
k -= 1;
}
if(i<k){
cout << "3. i:" << i << " k:"<<k<<" UserIDs.at(i):" << userIDs.at(i) << " UserID.at(k) : " << userIDs.at(k) << endl;
temp = userIDs.at(i);
userIDs.at(i) = userIDs.at(k);
userIDs.at(k) = temp;
i++;
k--;
}
cout << "4. i:" << i << " k:" << k << endl;
}
cout << " 5. k:" << k << endl;
return k;
}
void Quicksort(vector<string>& userIDs, int i, int k) {
cout << "Quicksort i:" << i << " k:" << k << endl;
if (i >= k) {
return;
}
int lowEndIndex = Partition(userIDs, i, k);
cout << "Quicksort lowEndIndex:" << lowEndIndex << endl;
Quicksort(userIDs, i, lowEndIndex);
Quicksort(userIDs, lowEndIndex+1, k);
}
When I input this list:
BigBen
GardenHeart
GreyMare
TeenPunch
WhiteSand
LifeRacer
Doom
AlienBrain
I get:
AlienBrain
BigBen
GreyMare
GardenHeart
Doom
LifeRacer
TeenPunch
WhiteSand
Why is Doom not in the correct place?
#include <bits/stdc++.h>
using namespace std;
int Partition(vector<string>& userIDs, int i, int k) {
int pivot = i;
string pivotValue = userIDs[pivot];
string temp;
int leftIndex = i;
int rightIndex = k;
while(i<k) {
while (userIDs[i].compare(pivotValue)<=0) {
i++;
if(i >= rightIndex) break;
}
while (pivotValue.compare(userIDs[k])<=0) {;
k--;
if(k <= leftIndex) break;
}
if(i<k){
temp = userIDs[i];
userIDs[i] = userIDs[k];
userIDs[k] = temp;
}
}
// swap
userIDs[pivot] = userIDs[k];
userIDs[k] = pivotValue;
return k;
}
void Quicksort(vector<string>& userIDs, int i, int k) {
if (i >= k) {
return;
}
int lowEndIndex = Partition(userIDs, i, k);
Quicksort(userIDs, i, lowEndIndex - 1);
Quicksort(userIDs, lowEndIndex + 1, k);
}
int main() {
vector<string> userIDs = {"BigBen", "GardenHeart", "GreyMare", "TeenPunch",
"WhiteSand", "LifeRacer", "Doom", "AlienBrain" };
Quicksort(userIDs, 0, userIDs.size() - 1);
for(auto& c: userIDs) cout << c << " ";
cout << endl;
return 0;
}
Fixed the code and tested. Now it works. What were the problems?
As far as I noticed, firstly you didn't put break() statements within the while loops in case i or k exceeds the boundaries of the vector. I've changed the pivot from middle element to first element, but it's just my preference, you can implement the quicksort algorithm with your pivot in the middle, not a big deal. I've called first Quicksort() with lowEndIndex - 1 rather than lowEndIndex. I've used [] operator rather than at(), but again it's my preference. I guess the main problems were that break stuff and calling the quicksort method with lowEndIndex rather than lowEndIndex - 1.
Output:
AlienBrain BigBen Doom GardenHeart GreyMare LifeRacer TeenPunch WhiteSand

error: overloaded function with no contextual type information usinf LEMON-graph-library

So I am implementing a Benders procedure using lazy constraints from GUROBI. As part of the subproblem procedure I need to process a graph using Breadth First Search, for which I am using LEMON. I am trying to implement use a visitor for the BFS search. However when I try to access the map of reached nodes using bfs.reached() I get a compiler (I suppose) error.
Here is the callback class implementation so far:
typedef ListDigraph::Node Node;
typedef ListDigraph::Arc Arc;
typedef ListDigraph::ArcMap<double> ArcDou;
typedef ListDigraph::NodeMap<double> NodeDou;
typedef ListDigraph::ArcMap<int> ArcInt;
typedef ListDigraph::ArcMap<bool> ArcBool;
typedef ListDigraph::NodeMap<int> NodeInt;
typedef ListDigraph::NodeIt NodeIt;
typedef ReverseDigraph<ListDigraph>::NodeIt NodeIt_rev;
typedef ListDigraph::ArcIt ArcIt;
class BendersSub: public GRBCallback
{
public:
const Instance_data &ins;
const vec4GRBVar &X;
const vec1GRBvar &u;
vec2GRBVar &p;
GRBModel &modelSubD;
BendersSub(const Instance_data &ins, const vec4GRBVar &X, const vec1GRBvar &u, vec2GRBVar &p, GRBModel &modelSubD)
:ins(ins), X(X), u(u), p(p),modelSubD(modelSubD){
//cout << "\n\tI:" << ins.I << " J:" << ins.J << " T:" << ins.T << " V:" << ins.V << flush;
}
protected:
void callback() {
try {
if (where == GRB_CB_MIPSOL) {
cout << "\n -- Entering Callback -- " << flush;
string var_name;
int I = ins.I , J = ins.I , T = ins.T , V = ins.V,i,j,k,t,v;
ListDigraph grafo;
Node x;
for( int t(0); t < ins.T+1; t++)
for ( int i(0); i < ins.I; i++)
x = grafo.addNode();
Arc arco;
int count( 0 );
for(t = 0; t < ins.T; ++t){
for(i = 0; i < ins.I; ++i){
for(j = 0; j < ins.J; ++j){
if ( i == j ){
arco = grafo.addArc(grafo.nodeFromId(i + ins.I * t),grafo.nodeFromId(j + (ins.I * (t+1))));
}else if ( (t + ins.tau.at(i).at(j)) <= ins.T-1 ){
arco = grafo.addArc(grafo.nodeFromId(i + ins.I * t),grafo.nodeFromId(j + ins.I * (t + ins.tau.at(i).at(j))));
}
else if ( (t + ins.tau.at(i).at(j)) > ins.T-1 ){
arco = grafo.addArc(grafo.nodeFromId(i + ins.I * t),grafo.nodeFromId(((ins.I*(ins.T+1)+1))-1-(ins.I)+j)) ;
}
}
}
}
NodeDou divergence (grafo);
ArcDou costo (grafo);
ArcBool filter (grafo, true);
NodeDou potential (grafo);
ReverseDigraph<ListDigraph> grafo_r(grafo);
using Visitor = Visitor_AcSup<NodeDou>;
for ( int v(0); v < V; v++){
double sum_sup(0.0);
Visitor visitor(grafo_r, divergence, sum_sup);
cout << "\nsum_sup: " << sum_sup << flush;
for (t = 0; t < T; t++){
for(i = 0; i < I ; i++){
if(divergence[grafo.nodeFromId(flat_ixt(ins,t,i))] < -EPS3){
BfsVisit<ReverseDigraph<ListDigraph>, Visitor> bfs(grafo_r,visitor);
bfs.run(grafo.nodeFromId(flat_ixt(ins,t,i)));
if( (sum_sup-fabs(divergence[grafo.nodeFromId(flat_ixt(ins,t,i))])) < -EPS4 ){
cout << "\nBuild Ray" << flush;
}
}
}
}
for (NodeIt_rev u(grafo_r); u != INVALID; ++u){
/*The error does not show when I comment this line.*/
cout << "\nId: " << grafo.id(u) << setw(10) << bfs.reached(u) << flush;
}
cout << "\nsum_sup: " << sum_sup << flush;
.
/* Remaining code */
.
.
}/*end_if v*/
//cout << "\n -- Exiting Callback -- " << flush;
}
}catch (GRBException e) {
cout << "Error number: " << e.getErrorCode() << endl;
cout << e.getMessage() << endl;
exit(EXIT_FAILURE);
}catch (const exception &exc){
cerr << "\nCallback - " << exc.what() << flush;
exit(EXIT_FAILURE);
}catch (...) {
cout << "Error during callback" << endl;
exit(EXIT_FAILURE);
}
}
};
Here is the (incomplete visitor) implementation.
template <typename DivMap >
class Visitor_AcSup : public BfsVisitor< const ReverseDigraph<ListDigraph> > {
public:
Visitor_AcSup(const ReverseDigraph<ListDigraph>& _graph, DivMap& _dirMap, double& _sum_sup)
: graph(_graph), dirMap(_dirMap), sum_sup(_sum_sup){
cout << "\n --Calling constructor of Visitor_AcSup -- " << endl;
sum_sup = 0.0;
}
void start (const Node &node){
//cout << "\nstart Node: " << graph.id(node) << flush;
sum_sup -= dirMap[node];
}
void reach (const Node &node){
//cout << "\nReach Node: " << graph.id(node) << flush;
}
void process (const Node &node){
//cout << "\nProcess Node: " << graph.id(node) << setw(5) << dirMap[node] << flush;
sum_sup += dirMap[node];
}
void discover(const Arc& arc) {
//cout << "\tDiscover Arc: " << graph.id(arc) << flush;
}
void examine(const Arc& arc) {
//cout << "\tExamine Arc: " << graph.id(arc) << flush;
}
private:
const ReverseDigraph<ListDigraph>& graph;
DivMap& dirMap;
double& sum_sup;
The error looks like this
functions.cpp:1845:59: error: overloaded function with no contextual type information
cout << "\nId: " << grafo.id(u) << setw(10) << bfs.reached(u) << flush;
^~~~~~~
Makefile:27: recipe for target 'VAP' failed
I am clueless about what is happening as the only error that comes up to my mind is conflict of keywords between namespaces
using namespace lemon;
using namespace lemon::concepts;
using namespace std;
but have found no resolution to this. I am a newbie in C++, so that I am asking you guys where this could possibly come from.

Returns garbage value instead of 0 or 1 in c++

I am trying to return integer from the following method in c++:
int check_for_chef(string str1,string str2,int M,int N)
{
if ( N == -1 )
{
cout << "I am returning 1." <<endl;
return 1;
}
else if ( N > M )
{
cout << " I am returning 0." <<endl;
return 0;
}
else
{
if ( str1[M] == str2[N])
{
location[N] = M;
cout << "location is: "<<location[N]<<endl;
check_for_chef(str1,str2,M - 1, N - 1);
}
else
{
check_for_chef(str1,str2,M - 1, N);
}
}
}
But, what I am getting while returning is :
Returned value is: 35668224
Whole code is here:
#include <iostream>
#include <string>
using namespace std;
int location[4];
int check_for_chef(string str1,string str2,int M,int N)
{
if ( N == -1 )
{
cout << "I am returning 1." <<endl;
return 1;
}
else if ( N > M )
{
cout << " I am returning 0." <<endl;
return 0;
}
else
{
if ( str1[M] == str2[N])
{
location[N] = M;
cout << "location is: "<<location[N]<<endl;
check_for_chef(str1,str2,M - 1, N - 1);
}
else
{
check_for_chef(str1,str2,M - 1, N);
}
}
}
int main()
{
int count = 0;
string original_string;
cin >> original_string;
string chef = "CHEF";
int M = original_string.size();
int N = 4;
while ( 1 )
{
cout << "Returned value is: " << check_for_chef(original_string,chef,M - 1, N - 1);
cout << " i am in while."<<endl;
count++;
original_string.erase(location[3],1);
cout << "the original_string : " << original_string <<endl;
original_string.erase(location[2],1);
cout << "the original_string : " << original_string <<endl;
original_string.erase(location[1],1);
cout << "the original_string : " << original_string <<endl;
original_string.erase(location[0],1);
cout << "the original_string : " << original_string <<endl;
cout << "the original_string : " << original_string <<endl;
M = original_string.size();
cout << "size is :" << M <<endl;
if ( M < N )
break;
}
cout << count <<endl;
}
Please help me to solve this problem.
I don't see two more return in the code
I have added in the commented lines below:
int check_for_chef(string str1,string str2,int M,int N)
{
if ( N == -1 )
{
cout << "I am returning 1." <<endl;
return 1;
}
else if ( N > M )
{
cout << " I am returning 0." <<endl;
return 0;
}
else
{
if ( str1[M] == str2[N])
{
location[N] = M;
cout << "location is: "<<location[N]<<endl;
return check_for_chef(str1,str2,M - 1, N - 1); // here 1st RETURN
}
else
{
return check_for_chef(str1,str2,M - 1, N); // here 2nd RETURN
}
}
}
Your code does not return anything expicitly in the else branch.
Values in x84 usually are returned via EAX register, so if you do not return anything - it behaves like an uninitialized variable.

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.

Igraph (C) returns bad vertex ids

I am trying to load a simple graph in the gml format (I can upload it if needed) and the compute its adjacency list and print it for each vertex.
Here is what I am doing:
int
main(int argc, char *argv[])
{
igraph_t g;
igraph_adjlist_t adjlist;
int num_edges, num_vertices;
FILE *ifile;
ifile = fopen("example.gml", "r");
igraph_read_graph_gml(&g, ifile);
fclose(ifile);
n_vertices = igraph_vcount(&g);
cout << "vertices: " << n_vertices << endl;
igraph_adjlist_init(&g, &adjlist, IGRAPH_OUT);
igraph_vector_t *vect_adj;
for (int n = 0; n < n_vertices; n++)
{
igraph_vs_t adc;
igraph_vs_adj(&adc, n, IGRAPH_OUT);
cout << "TYPE " << igraph_vs_type(&adc) << "\n";
vect_adj = (igraph_vector_t *)igraph_adjlist_get(&adjlist, n);
printf("\nvertex %d n adjs %ld\n", n, igraph_vector_size(vect_adj));
for (int f = 0; f < igraph_vector_size(vect_adj); f++)
{
cout << "node id " << (long int)igraph_vector_e(vect_adj, f) << endl;
long int neighbor = VECTOR(*vect_adj)[f];
cout << "nid " << neighbor << endl;
}
}
igraph_destroy(&g);
}
but what happens is that I am always getting 0 as an id as if there had been some type conversion issue. What am I doing wrong here?
I guess the point here is to use a typed vector like igraph_vector_int_t and typed functions as well, igraph_vector_int_size.