pthread_create passing in dynamic vector array into argument - c++

how do I cast a void pointer vector array into a vector array?
vector<string>* vArray = new vector<string[numThreads];
p_thread_create(&my_thread[1], NULL, &function, (void)* vArray[1]);
void* function (vector<string> vArray[])
{
//?? casting?
}
when passed in as argument (void)* vArray[1] it says invalid cast...
And can pthread create take in more arguments, say 2, if the function takes 2 parameters? Thanks
Here's my complete code
#include <iostream>
#include <iomanip>
#include <iterator>
#include <sstream>
#include <fstream>
#include <string>
#include <vector>
#include <pthread.h>
#include <queue>
using namespace std;
int array[5] = { 0, 0, 0, 0, 0 };
void* readData(void* arg)
{
string fileName = "Wisconsin.txt";
cout << "HERE!"<< endl;
ifstream cities(fileName.c_str());
string line;
while(!cities.eof()){
getline(cities, line);
if(line != "") {
int commaPos = line.find(',');
int popul = atoi(line.substr(commaPos + 2).c_str());
int x = popul;
if (x >= 1 && x <= 999)
{
array[0]++;
} else
if (x >= 1000 && x <= 9999)
{
array[1]++;
} else
if (x >= 10000 && x <= 99999)
{
array[2]++;
} else
if (x >= 100000 && x <= 999999)
{
array[3]++;
} else
if (x >= 1000000)
{
array[4]++;
}
} // end of IF
} // end of while
}
int main()
{
int numThreads;
ifstream ifs("states.txt");
std::string str((std::istreambuf_iterator<char>(ifs)),
std::istreambuf_iterator<char>());
stringstream ss(str);
int fileCount = 0;
string fileName;
while (ss >> fileName)
{
fileCount++;
}
cout << fileCount;
string* filesArr = new string[fileCount];
ss.clear();
ss.seekg(0, std::ios::beg);
for (int i = 0; i < fileCount; i++)
{
ss >> filesArr[i];
}
cout << "Enter number of threads: ";
cin >> numThreads;
vector<string>* vArray = new vector<string>[numThreads];
for (int i = 0; i < fileCount; i++)
{
vArray[i % numThreads].insert(vArray[i % numThreads].begin(), filesArr[i]);
}
//queue<string>* queueArr = new queue<string>[numThreads];
//for (int i = 0; i < fileCount; i++)
// queueArr[i % numThreads].push(filesArr[i]);
for(int i = 0; i < numThreads; i ++)
{
cout << endl;
cout << "FOR THREAD " << i + 1 << ":" << endl;
for (std::vector<string>::iterator it = vArray[i].begin(); it != vArray[i].end(); it++)
{
cout << *it << endl;
}
}
pthread_t my_thread[numThreads];
int ret = pthread_create(&my_thread[1], NULL, &readData, (void*)(vArray+1));
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
///////////// ERROR HERE!
pthread_join(my_thread[1], ret);
// for (int id = 0; id < numThreads; id++)
// {
//}
pthread_join(my_thread[1]);
cout << endl;
printf("%-20s", "1-999:");
cout << array[0] << endl;
printf("%-20s", "1,000 - 9,999:");
cout << array[1] << endl;
printf("%-20s", "10,000-99,999:");
cout << (array[2]) << endl;
printf("%-20s", "100,000-999,999:");
cout << (array[3]) << endl;
printf("%-20s", "1,000,000+:");
cout << (array[4]) << endl;
//int pos;
//string token;
//while ((pos = s.find(delimiter))
cin.get();
return 0;
}
pthread join doesn't seem to be working now.. compiling it return me: too few arguments to function 'int pthread_join(pthread_t, void**)

After cleaning up your code:
#include <iostream>
#include <vector>
using namespace std;
const int numThreads = 10;
void * thread_body (void * param)
{
// retrieve parameter
string& prm = *(string *)param;
// use it
cout << prm << endl;
return NULL;
}
int main() {
vector<string >threadPrm(numThreads);
vector<pthread_t>threadId (numThreads);
threadPrm[1] = "Hello";
pthread_create(&threadId[1], NULL, thread_body, &threadPrm[1]);
pthread_join (threadId[1], NULL);
return 0;
}
You don't seem to be comfortable with
vectors
pointers and references
variable naming
Also, trying to shut the compiler up with static casts is a sure way to produce silly code.
The point is usually to make the code run, not to compile it at all cost.
Lastly, you can answer your own question about the number of parameters a posix thread can take by reading the manual

Related

getting a OUTOFRANGE error with vector in c++ when using insert method

I am getting a OUTOFRANGE error with vector in c++ when using insert method. I don't know why this is happening but I was able to narrow down the problem to one line through debugging. Here is the full code.
//
#include <cstdio>
#include <iostream>
#include <vector>
#include <fstream>
#include <cassert>
#include <string>
using namespace std;
class suffixArray{
public: suffixArray(std:: string concatenated ){
vector<int> attempt1;
const int size = (int)concatenated.length();
int rank[7] = {};
char *suffixPointers[concatenated.length()];
int value[concatenated.length()];
for(int i =0; i <= size-1; i++){
suffixPointers[i] = &concatenated[i];
value[i] = (int)concatenated[i];
}
std::cout << "[";
for(int i = 0; i<= size-1; i++){
std::cout <<value[i] << " ";
}
std::cout << "]"<< std:: endl;
for(int i = 0; i<=size -1; i++){
if(i == 0){
rank[i] = i;
attempt1.push_back(i);
}
else if(value[i] > value[i-1]){
rank[i] = i;
attempt1.push_back(i);
}else{
int current =i;
int savedValue = value[i];
int prevSavedRank;
int indexcounter = i;
while(savedValue <= value[attempt1.at(indexcounter-1)] && indexcounter - 1 >= 0 ){
indexcounter--;
}
cout << indexcounter << endl;
attempt1.insert(attempt1.begin() + indexcounter ,i);
// while(savedValue <= value[rank[current-1]] && current-1 >= 0){
// prevSavedRank= rank[current-1];
// rank[current-1] = i;
// rank[current] = prevSavedRank;
// current--;
// }
}
}
int now;
for(int i = 0; i<= 3; i++){
now = attempt1[i];
std::cout << now << " ";
}
}
};
void read_file(string filename, string& contents, int& num_lines){
ifstream f;
f.open(filename.c_str());
string line;
contents = "";
num_lines = 0;
while(getline(f, line)){
contents.append(line.substr(0, line.length()));
num_lines++;
}
f.close();
}
int main(int argc, const char* argv[]) {
std:: string test = "BANANA$";
suffixArray testString (test);
string fn;
string contents;
int num_lines;
cout << "File 1:" << endl;
cin>> fn;
read_file(fn, contents, num_lines);
cout << "Read: " << fn << "\n";
cout << " * " << num_lines << " lines\n";
cout << " * " << contents.length() << " characters (excluding newlines)\n";
//cout <<" * " << contents << endl;
// char * contents_cstring = (char*)contents.c_str();
//for(int i =0; i< contents.length(); i++){
// assert(contents_cstring[i] == *(contents_cstring + 1));
// assert(contents_cstring[i] == contents.at(i));
//}
//assert(contents_cstring[contents.length()] == '\0');
return 0;
}
I have narrowed down the problem to be the problem to be from this line, but can not figure out why it is occurring, or how to fix it.
attempt1.insert(attempt1.begin() + indexcounter ,i);
Consider the first time the program reaches
int indexcounter = i;
while(savedValue <= value[attempt1.at(indexcounter-1)] && indexcounter - 1 >= 0){
indexcounter--;
}
i will be 1. indexcounter-1 will be 0. If the loop is entered,
int indexcounter = 1;
while(savedValue <= value[attempt1.at(0)] && 0 >= 0 ){
1--;
}
OK, so what happens the next time?
while(savedValue <= value[attempt1.at(-1)] && -1 >= 0 ){
0--;
}
value[attempt1.at(-1)] happens before -1 >= 0, s the trap to prevent -1 fails. Reverse the order of the tests.
while(indexcounter - 1 >= 0 && savedValue <= value[attempt1.at(indexcounter-1)])
Could be more bugs, but after that the program hangs and asks for a file that I don't have.

C++ code crashes instantly due to memory issues

This code should read a .pnm file. I tried to run it with 2 resolutions:
200x200 px: Here everything works just fine.
500x281 px: Code instantly crashes, raising a SIGSEGV error.
As far as I know, SIGSEGV is related to memory issues. I have 8GB of RAM, a quantity that I judge to be enough to run this. I don't have any idea about why it's happening and how to fix it.
Code
#define IO_ERROR (5)
#define X_DIMENSION (500)
#define Y_DIMENSION (281)
#define C_DIMENSION (3)
#define HEADER_SIZE (3)
#define BODY_SIZE (X_DIMENSION * Y_DIMENSION * C_DIMENSION)
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int readImage(string fileName, string *imgHeader, string *imgBody)
{
ifstream inputFile(fileName);
if (!inputFile.is_open())
return IO_ERROR;
string line;
int count = 0;
while (getline(inputFile, line)) {
if (line.find("#") != string::npos)
continue;
if (count < 3)
imgHeader[count] = line;
else
imgBody[count - HEADER_SIZE] = line;
count++;
}
inputFile.close();
return 0;
}
void numericParser(const string *imgBody, unsigned char *numericBody)
{
int i = 0;
while(i < BODY_SIZE) {
numericBody[i] = (unsigned) atoi(imgBody[i].c_str());
i++;
}
}
void rgbParser(const string *imgBody, unsigned char rgbMatrix[X_DIMENSION][Y_DIMENSION][C_DIMENSION])
{
unsigned char numericBody[BODY_SIZE];
numericParser(imgBody, numericBody);
int k = 0;
for (int i = 0; i < X_DIMENSION; i++) {
for (int j = 0; j < Y_DIMENSION; j++) {
for (int c = 0; c < 3; c++) {
rgbMatrix[i][j][c] = numericBody[k];
k++;
}
}
}
}
void printInfo(const string *header, const string *body)
{
cout << "#-*- Image Header -*-" << endl;
for (int i = 0; i < HEADER_SIZE; i++) {
cout << header[i] << endl;
}
cout << "#-*- Image Body -*-";
for (int i = 0; i < 5 * C_DIMENSION; i++) {
if (i % 3 == 0) cout << endl << "R: " << body[i];
else if (i % 3 == 1) cout << " G: " << body[i];
else cout << " B: " << body[i];
}
cout << endl << ". . ." << endl;
}
int main()
{
string fileName;
cout << "File name: ";
cin >> fileName;
string imgHeader[HEADER_SIZE];
string imgBody[BODY_SIZE];
if(readImage(fileName, imgHeader, imgBody) == IO_ERROR)
return IO_ERROR;
// printInfo(imageData);
unsigned char rgbMatrix[X_DIMENSION][Y_DIMENSION][C_DIMENSION];
rgbParser(imgBody, rgbMatrix);
return 0;
}
Additional Info
I'm on Arch Linux 64-bit, using CLion as IDE.

C++ Console is blank when program is run

This might be a stupid question I'm still very new to coding. For my CS class I was given code for the basics of a boardgame. When I try to run the code it just comes up blank in my console, I tried to print "check" at the very beginning of main but still nothing prints to the console. No errors come up
#include <iostream>
#include <string>
#include <fstream>
#include <ctime>
#include <cstdlib>
using namespace std;
class square {
private:
int move;
string message;
char symbol;
public:
square();
void print();
int action();
void set(int, char, string);
};
void print_board(square[], int, int);
void read_board(square[]);
void check_position(int &);
const int board_length = 20;
int main() {
cout << "check";
int current_player = 1, roll;
int player1_position = 0, player2_position = 0;
square the_board[board_length];
srand(time(NULL));
read_board(the_board);
print_board(the_board, player1_position, 1);
print_board(the_board, player2_position, 2);
do {
cout << "\n\n\nPlayer " << current_player << " type enter to roll.\n";
cin.ignore();
roll = 1 + (rand() % 5);
cout << "Player " << current_player << " rolled a " << roll << ".\n";
if (current_player == 1) {
player1_position += roll;
check_position(player1_position);
player1_position += the_board[player1_position].action();
check_position(player1_position);
} else {
player2_position += roll;
check_position(player2_position);
player2_position += the_board[player2_position].action();
check_position(player2_position);
}
print_board(the_board, player1_position, 1);
print_board(the_board, player2_position, 2);
current_player = (current_player % 2) + 1;
} while ((player1_position < board_length-1) && (player2_position < board_length - 1));
current_player = (current_player % 2) + 1;
cout << "\nPlayer " << current_player << " Wins!!!\n";
cin.ignore();
return 0;
}
void read_board(square b[]) {
ifstream infile;
infile.open("game.txt");
int square_number, square_move;
string square_message;
char square_symbol;
while (!infile.eof()) {
infile >> square_number >> square_move >> square_symbol;
getline(infile, square_message);
if (square_number < board_length) {
b[square_number].set(square_move, square_symbol, square_message);
}
}
}
void print_board(square b[], int player_position, int player_number) {
for (int i=0; i < board_length; i++) {
if (i != player_position) {
b[i].print();
} else {
cout << player_number;
}
}
cout << "Goal\n";
for (int i=0; i < board_length; i++) {
cout << "-";
}
cout << "\n";
}
void check_position(int &p) {
if (p < 0) {
p = 0;
}
if (p >= board_length) {
p = board_length - 1;
}
}
square::square() {
symbol = ' ';
move = 0;
message = "";
}
int square::action() {
cout << message << endl;
return move;
}
void square::print() {
cout << symbol;
}
void square::set (int m, char s, string a_message) {
move = m;
symbol = s;
message = a_message;
}
Modify you read_board() to
void read_board(square b[]) {
ifstream infile;
infile.open("game.txt");
int square_number, square_move;
string square_message;
char square_symbol;
while (infile >> square_number >> square_move >> square_symbol) {
getline(infile, square_message);
if (square_number < board_length) {
b[square_number].set(square_move, square_symbol, quare_message);
}
}
}
Change cout<<"check"; to cout<<"check"<<endl;
Without the new line added, the out buffer is not flushed before your code gets hung in your read_board function

read int per line c++ error needs solution

hey guys I need help for my read code seems not working properly here's the code. The problem is as shown in the picture, the compiler are supposed to display all 1 million int value but it seems that my write or the display code was wrong. It shows nothing like it's not even reading.
#include <iostream>
#include <fstream>
#include <string>
#include <iomanip>
#include <vector>
#include <omp.h>
#include <ctime>
#include <cstdlib>
using namespace std;
int* CreateArray( int*);
void shellSortParallel( int*, int);
void shellSortSequential(int*, int);
void InsertSort( int*, int, int, int);
int main()
{
int array_size = 1000000;
int n=0;
int* arr=new int[array_size];
ifstream fin("OUTPUT1.txt");
if(! fin)
{
cout << "File could not be opened." << endl;
}
else
{
cout << "File Opened successfully!!!. Reading data from file into array" << endl;
int data;
while(fin>>data)
{
arr[n] = data;
n++;
}
cout << "Displaying Array..." << endl << endl;
for(int i = 0; i < array_size; i++)
{
cout << arr[i];
}
}
fin.close();
int length = 1000000;
double endTime = 0, startTime = 0, totalTime = 0;
double start, end;
cout << "Program is now sorting using shell sort" <<endl;
startTime = time(NULL);
start = omp_get_wtime();// Start performance timer 1 run
shellSortParallel(arr, length);//Run the algorithm
end = omp_get_wtime();// End performance timer 1 run
endTime = time(NULL);
totalTime = endTime - startTime;
cout << "This is the time it took to run. " << totalTime << endl;// time in seconds
int stupid = 0;
cin >> stupid;
cout << "Program has completed all tasks!!" << endl;
return 0;
}
void shellSortParallel(int array[], int length)
{
int h;
int j = 0;
int temp = 0;
int i = 0;
for(h =length/2; h > 0; h = h/2)
{
#pragma omp parallel for shared( array, length, h, i) default(none)
for( i = 0; i < h; i++)
{
//int ID = omp_get_thread_num();
InsertSort(array, i, length, h);
}
}
}
void InsertSort(int arr[], int i, int length, int half)
{
//cout << ID << " ";
int temp = 0;
int j = 0;
for (int f = half + i; f < length; f = f + half)
{
j = f;
while(j > i && arr[j-half] > arr[j])
{
temp = arr[j];
arr[j] = arr[j-half];
arr[j-half] = temp;
j = j -half;
}
}
}
and here is the short version of the file that I'm going to read. Its a random number between 1 to 1million per line
2377763
88764877846
281327
60
625
86
646127818
14551
2177645
32033
1826761
555173
3415445377
32430
1101
any help would be much appreciate, thank you before
By if(fin>>data) you are not just testing, but retrieving data from stream. I suggest use ifs.good() for testing. Overall, you can write such a code instead
std::ifstream fin ("OUTPUT1.txt", std::ifstream::in);
char c = fin.get();
while (fin.good())
{
std::cout << c;
c = fin.get();
}
arr[n-1] = '\0'; is not correct because it's not an array of character so don't mind.
to correct it:
int data;
while(fin>>data)
{
arr[n] = data;
n++;
}
cout << "Displaying Array..." << endl << endl;
for(int i = 0; i < array_size; i++)
{
cout << arr[i];
}
why allocating such huge array of integers? use vector is a good thing:
vector<int> vec;
ifstream fin("OUTPUT1.txt");
int data;
while(fin >> data)
{
vec.push_back(data);
}
cout << "Displaying Array..." << endl << endl;
for(int i = 0; i < vec.size(); i++)
cout << vec[i] << endl;
fin.close();
88764877846 out band of an integer which causes the loop stop reading so you have to either get values as strings then convert into __int64 or __int128
to read values as strings:
string sLine;
int nLines = 0;
ifstream fin("OUTPUT1.txt");
// first read to get number of lines
while(getline(fin, sLine))
nLines++;
//create an array of strings
string* pstrValues = new string[nLines];
// set the get pointer to the beginning of file because the previous read moved it
fin.clear();
fin.seekg(0, ios::beg);
int i = 0;
while(getline(fin, sLine))
{
pstrValues[i] = sLine;
i++;
}
cout << "Displaying Array..." << endl << endl;
for( i = 0; i < nLines; i++)
cout << pstrValues[i] << endl;
fin.close();
now you have an array of strings convert it to int values but you must convert to __int64 because as I said there are values bigger than size of int (4bytes)

C++ "Count the number of collisions at each slot in the hash table"

I'm suppose to create a Dictionary as a Hash Table with Linked List to spell check a text document. I read in the file "words.txt" to create the dictionary. Also, I have to count/display the number of collisions at each slot in the hash table when I load in the dictionary "words.txt"
I'm given the source code for the HashTable Class with Linked List as followed :
hashtable.cpp (#include "listtools.cpp" since its using templates)
#include <iostream>
#include <string>
#include "listtools.h"
#include "listtools.cpp"
#include "hashtable.h"
using LinkedListSavitch::Node;
using LinkedListSavitch::search;
using LinkedListSavitch::headInsert;
using namespace std;
#define HASH_WEIGHT 31
namespace HashTableSavitch
{
HashTable::HashTable()
{
for (int i = 0; i < SIZE; i++)
{
hashArray[i] = NULL;
//array for collisons
collisionArray[i] = 0;
}
}
HashTable::~HashTable()
{
for (int i=0; i<SIZE; i++)
{
Node<string> *next = hashArray[i];
while (next != NULL)
{
Node<string> *discard = next;
next = next->getLink( );
delete discard;
}
}
}
unsigned int HashTable::computeHash(string s) const
{
unsigned int hash = 0;
for (unsigned int i = 0; i < s.length( ); i++)
{
hash = HASH_WEIGHT * hash + s[i];
}
return hash % SIZE;
}
bool HashTable::containsString(string target) const
{
int hash = this->computeHash(target);
Node<string>* result = search(hashArray[hash], target);
if (result == NULL)
return false;
else
return true;
}
void HashTable::put(string s)
{
int count = 0;
int hash = computeHash(s);
if (search(hashArray[hash], s) == NULL)
{
// Only add the target if it's not in the list
headInsert(hashArray[hash], s);
}
else
{
collisionArray[hash]++;
}
void HashTable::printArray()
{
int number;
for(int i = 0; i < SIZE; i++)
{
number = collisionArray[i];
cout << "----------------\n";
cout << "index = " << i << endl;
cout << "Collisions = " << number << endl;
cout << "----------------\n";
}
}
} // HashTableSavitch
my main.cpp file
#include <iostream>
#include <fstream>
#include <cctype>
#include <algorithm>
#include <cstring>
#include <string>
#include "hashtable.h"
using namespace std;
using HashTableSavitch::HashTable;
void upToLow(string & str);
void removePunct(string & str);
int main()
{
HashTable h;
string currWord;
string word;
int countMisspelled = 0;
int countCorrect = 0;
//Get input from words.rtf
ifstream dictionary("words.txt");
//File checking
if (dictionary.fail())
{
cout << "File does not exist" << endl;
cout << "Exit program" << endl;
}
//Create the dictionary as a hash table
while(dictionary >> currWord)
{
h.put(currWord);
}
dictionary.close();
//display collisions
h.printArray();
//Get input from gettysburg_address.txt
ifstream input("gettysburg_address.txt");
//File checking
if (input.fail())
{
cout << "File does not exist" << endl;
cout << "Exit program" << endl;
}
//Spell check gettysburg_address.txt
cout << "Misspelled words : " << endl;
cout << endl;
//If a word is not in the dictionary assume misspelled
while(input >> word)
{
removePunct(word);
upToLow(word);
if(h.containsString(word) == false)
{
countMisspelled++; // Increment misspelled words count
cout << word << " ";
if(countMisspelled % 20 == 0) // Display misspelled words 20 per line
{
cout << endl;
}
}
else
{
countCorrect++; // Increment correct words count
}
}
input.close();
cout << endl;
cout << endl;
cout << "Number of misspelled words : " << countMisspelled << endl;
cout << "Number of correct words : " << countCorrect << endl;
return 0;
}
/*Function to convert uppercase letters to lowercase*/
void upToLow(string & str)
{
for (unsigned int i = 0; i < strlen(str.c_str()); i++)
if (str[i] >= 0x41 && str[i] <= 0x5A)
str[i] = str[i] + 0x20;
}
/*Function to remove punctuation from string*/
void removePunct(string & str)
{
str.erase(remove_if(str.begin(), str.end(), static_cast<int(*)(int)>(&ispunct)),str.end());
}
Is there a simple way to count the number of collisions at each slot when loading in "words.txt" ? If I implement a count variable in the "put" function I can get the total number of collisions, but I'm not quite sure how to count/display the number of collisions at each slot of the hash table. Any help/tips is appreciated.
EDIT :
Followed Joe's advice and now I'm wondering how I could display the number of collisions at each slot. I made a void function to do just that but it displays the number of collisions at each slot to be 0. Anyone know what I should do?
Probably the simplest way is declare an array in an appropriate place
int collisionArray[SIZE];
initialize it to 0 in HashTable::HashTable()
HashTable::HashTable()
{
for (int i = 0; i < SIZE; i++)
{
hashArray[i] = NULL;
collisionArray[i] = 0;
}
}
then increment the appropriate element when a collision is found
void HashTable::put(string s)
{
int count = 0;
int hash = computeHash(s);
if (search(hashArray[hash], s) == NULL)
{
// Only add the target if it's not in the list
headInsert(hashArray[hash], s);
collisionArray[hash]++;
}
}