the visual studio gives E0028 [closed] - c++

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
I have a problem , the visual studio gives me error E0028 (the expression must have a constant value) in 40 line, the code:
#include <string>
#include <thread>
#include <iostream>
#include <ctime>
#include <cstdio>
using namespace std;
void start(int i, int number_of_test, int numtodo, int numwas)
{
for (int i = numwas; i < numtodo; i++)
for (int j = 2; j < i; j++)
{
if (i % j == 0)
break;
else if (i == j + 1)
cout << i << " ";
}
cout << endl;
}
int main() {
int i = 1;
int threads;
cout << "threads";
cin >> threads;
int number;
cout << "number";
cin >> number;
int number_of_test = 0;
int numtodo = 0;
int numwas = 0;
while (i < threads + 1)
{
if (i < threads + 1) {
i = i + 1;
number_of_test = number / threads;
numtodo = number_of_test * i;
numwas = numtodo / number_of_test;
thread t[i](start, int(i), number_of_test, numtodo, numwas);
t[i].join();
}
}
}
I want to do threads in loop, for example not to write 128 threads, just to run the loop and it run a lot of threads. line 40 :thread t[i](start, int(i), number_of_test, numtodo, numwas); , error in t[I], I need to fix it , but I don't know how , I need to do a lot of threads (like t1, than t2 etc..)

This line does not make sense (and may be the cause for the problem):
thread t[i](start, int(i), number_of_test, numtodo, numwas);
You should create an array or vector to store the thread objects. Example:
#include <thread>
#include <iostream>
#include <vector>
//void start(...
int main() {
std::cout << "threads: ";
size_t threads;
std::cin >> threads;
std::vector<std::thread> t(threads); // create a vector to hold the thread objects
int number;
std::cout << "number: ";
std::cin >> number;
if (number < t.size()) return 1;
int number_of_test = 0;
int numtodo = 0;
int numwas = 0;
// start all threads
for (size_t i = 0; i < t.size(); ++i)
{
number_of_test = number / t.size();
numtodo = number_of_test * (i+1);
numwas = numtodo / number_of_test;
// start one thread and store it in its place in the vector:
t[i] = std::thread(start, i, number_of_test, numtodo, numwas);
}
// join all threads
for (auto& th : t) th.join();
}

Related

Why segmentation fault with multithreading? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 1 year ago.
Improve this question
I am working on a project about multithreading. Here Operation is a class which contains a type, a key, a time and an answer.
Here is my code:
#include <cstdlib>
#include <fstream>
#include <string>
#include <iomanip>
#include <pthread.h>
#include <vector>
#include "block.h"
using namespace std;
std::vector<Operation> *data;
block_bloom_filter filter(10000000, 0.01);
int ans[30000000];
void *test(void *arg)
{
int thread_id = *((int *)arg);
for (auto &op : data[thread_id])
{
if (op.type == 1)
{
filter.insert(op);
}
else
{
filter.query(op);
}
}
return 0;
}
int main(int argc, char **argv)
{
int k = atoi(argv[1]);
int *op_num = new int[k];
data = new vector<Operation>[k];
for (int i = 0; i < k; i++)
{
string tmp = "data" + to_string(i + 1) + ".in";
const char *s = tmp.c_str();
ifstream fin;
fin.open(s);
fin >> op_num[i];
//data[i] = new Operation[op_num[i]];
for (int j = 0; j < op_num[i]; j++)
{
string tmp1;
fin >> tmp1;
if (tmp1 == "insert")
{
Operation tmp2;
tmp2.type = 1;
fin >> tmp2.key >> tmp2.time;
tmp2.ans = -1;
data[i].push_back(tmp2);
}
else
{
Operation tmp2;
tmp2.type = 2;
fin >> tmp2.key >> tmp2.time;
tmp2.ans = -1;
data[i].push_back(tmp2);
}
}
fin.close();
}
auto start = std::chrono::high_resolution_clock::now();
int num_threads = k;
pthread_t *threads = new pthread_t[num_threads];
//auto **threads = new thread *[num_threads];
//pthread_t *threads = new pthread_t[k];
/*for (int i = 0; i < num_threads; i++)
{
threads[i] = new thread(test, i);
}
for (int i = 0; i < num_threads; i++)
{
threads[i]->join();
}*/
for (int i = 0; i < k; i++)
{
pthread_create(&threads[i], NULL, test, (void *)&(i));
}
auto stop = std::chrono::high_resolution_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::microseconds>(stop - start);
//std::cerr << "duration = " << duration.count() << "us" << std::endl;
double time_used = duration.count() / 1e3;
std::ofstream f_time("time.out");
f_time << std::fixed << std::setprecision(3) << time_used << std::endl;
f_time.close();
for (int i = 0; i < k; i++)
{
for (int j = 0; j < op_num[i]; j++)
{
ans[data[i][j].time - 1] = data[i][j].ans;
}
}
ofstream fout;
fout.open("result.out");
for (int i = 0; i < 30000000; i++)
{
if (ans[i] >= 0)
fout << ans[i] << endl;
}
fout.close();
delete[] data;
delete[] threads;
delete[] op_num;
//pthread_exit(NULL);
}
My code can compile, but when running it shows segmentation fault and can only generate time.out no result.out. I've been working on it for a long time but still do not know why. Hope someone can help me.
Below is block.h
#include <algorithm>
#include <chrono>
#include <cmath>
#include <ctime>
#include <fstream>
#include <iostream>
#include <numeric>
#include <string>
#include <vector>
#include "Headers/MurmurHash3.h"
#include "xxHash/xxhash.c"
#define M_LN2 0.69314718055994530942
using namespace std;
typedef std::vector<bool> bit_vector;
class Operation
{
public:
int type; // 1: insert, 2: query
char key[17];
int time;
int ans;
};
int str_len = 16;
int cache_size = 64;
int block_size = 512;
int key_num = 10000000;
int slot_num = 1 << 27;
int hash_num = int((double)slot_num / key_num * M_LN2);
int block_num = (slot_num + block_size - 1) / block_size;
class bloom_filter
{
uint32_t size; // Probable Number of elements in universe
double fpr; // False positive rate
int m; // optimal size of bloom filter
int k; // Number of hash functions
bit_vector bloom;
public:
int get_size() { return size; }
double get_fpr() { return fpr; }
bloom_filter(int n, double fpr)
{
this->size = n;
this->fpr = fpr;
this->m = ceil(
-((n * log(fpr)) /
pow(log(2), 2.0))); // Natural logarithm m = −n ln p/(ln 2)2
// cout << m<< "\n";
this->k = ceil(
(m / n) * log(2)); // Calculate k k = (m/n) ln 2 􃱺 2-k ≈ 0.6185 m/n
// cout << k;
bloom.resize(m, false);
}
void insert(string S)
{
uint32_t *p = new uint32_t(1); // For storing Hash Vaue
const void *str = S.c_str(); // Convert string to C string to use as a
// parameter for constant void
int index;
// cout<<S.length()<<"\t"<<sizeof(str)<<"\n";
// cout<<S<<"\n";
for (int i = 0; i < k; i++)
{
// MurmurHash3_x64_128();
MurmurHash3_x86_32(str, S.length(), i + 1,
p); // String, String size
index = *p % m;
// cout<<*p<<"\t"<<index<<"\t";
bloom[index] = true;
}
// cout<<"\n";
// print();
}
/*void print()
{
for (int i = 0; i < bloom.size(); i++)
{
cout << bloom.at(i);
}
}*/
char query(string S)
{
uint32_t *p = new uint32_t(1); // For storing Hash Vaue
const void *str = S.c_str(); // Convert string to C string to use as a
// parameter for constant void
int index;
// cout << S.length() << "\t" << sizeof(str) << "\n";
// cout<<S<<"\n";
for (int i = 0; i < k; i++)
{
// MurmurHash3_x64_128();
MurmurHash3_x86_32(str, S.length(), i + 1,
p); // String, String size
index = *p % m;
// cout<<*p<<"\t"<<index<<"\t";
if (bloom[index] == false)
return 'N';
}
return 'Y';
}
};
class block_bloom_filter
{
int size; // Probable Number of elements in universe
double fpr; // False positive rate
int m; // optimal size of bloom filter
int k; // Number of hash functions
int s; // Number of bloom filters
bit_vector block_bloom;
int cache_line_size;
public:
int get_size() { return size; }
double get_fpr() { return fpr; }
block_bloom_filter(int n, double fpr)
{
this->size = n;
this->fpr = fpr;
this->m = ceil(
-((n * log(fpr)) /
pow(log(2), 2.0))); // Natural logarithm m = −n ln p/(ln 2)2
// cout << m << "\n";
this->k = ceil(
(m / n) * log(2)); // Calculate k k = (m/n) ln 2 􃱺 2-k ≈ 0.6185 m/n
// cout << k<<"\n";
this->cache_line_size = sysconf(_SC_LEVEL1_DCACHE_LINESIZE) * 8;
this->s =
ceil((double)m / cache_line_size); // Total number of Bloom Filters
// cout<<s<<"s valye\n";
block_bloom.resize(cache_line_size * s, false);
}
/*void insert(Operation &S)
{
int block_number;
int first_index, last_index;
int index;
uint32_t *p = new uint32_t(1); // For storing Hash Value
const void *str = S.key.c_str(); // Convert string to C string to use as a
// parameter for constant void
MurmurHash3_x86_32(str, sizeof(str), 1,
p); // String, String size//Find out block number
// if(s!=0)
block_number = *p % s;
first_index = block_number * cache_line_size;
for (int i = 1; i < k; i++)
{
// MurmurHash3_x64_128();
MurmurHash3_x86_32(str, S.key.length(), i + 1,
p); // String, String size
// cout<<*p<<"\n";
// cout<<"div="<<div << "\n";
index = (*p) % cache_line_size;
// cout<<index<<"\t";
// if(index>m) cout<<"\n"<<index<<"\tError detected\n";
// cout<<"\n"<<index<<"a\t\n";
// cout<<"\n"<<first_index<<"a\t\n";
// cout<<(index+first_index)<<"a\t\n";
block_bloom[index + first_index] = true;
}
// cout<<"\n";
// print();
}*/
XXH64_hash_t GetHash(const char *str)
{
return XXH3_64bits_withSeed(str, 16, /* Seed */ 123976235672331983ll);
}
void insert(Operation &s)
{
XXH64_hash_t hash = GetHash(s.key);
XXH64_hash_t hash1 = hash % m;
XXH64_hash_t hash2 = (hash / m) % m;
for (int i = 0; i < k; i++)
{
int pos = (hash1 + i * hash2) % m;
block_bloom[pos] = 1;
}
}
void query(Operation &s)
{
XXH64_hash_t hash = GetHash(s.key);
XXH64_hash_t hash1 = hash % m;
XXH64_hash_t hash2 = (hash / m) % m;
for (int i = 0; i < k; i++)
{
int pos = (hash1 + i * hash2) % m;
if (!block_bloom[pos])
{
s.ans = 0;
return;
}
}
s.ans = 1;
return;
}
};
for (int i = 0; i < k; i++)
{
pthread_create(&threads[i], NULL, test, (void *)&(i));
The third parameter to pthread_create(), the thread function's parameter, is a pointer to the loop variable. The thread function reads it, as follows:
void *test(void *arg)
{
int thread_id = *((int *)arg);
There are no guarantees whatsoever that this gets executed by the new execution thread before the parent execution thread increments i. When it comes to multiple execution threads, neither POSIX nor the C++ library gives you any guarantees as to the relative execution order of multiple threads.
All that pthread_create() guarantees you is that at some point in time later, which can before before or after pthread_create() returns, the new execution thread pops into existence and begins executing the thread function.
And it may very well be that one or more (if not all) execution threads finally begin executing, for real, after the for loop terminates and i gets destroyed. At which pointL when they do start executing, they will discover a pointer to a destroyed variable as their argument, and dereferencing it becomes undefined behavior.
Or, some of those execution threads get their gear running, at some point after they get created. By this time i's been incremented a couple of times already. So they both read the *(int *)arg, whose value is now -- who knows? And, just to make things interesting, both execution threads do this at the same time, and read the same value. At this point, the end result is already going to be garbage. It is clear that the intent here is for each execution thread getting a unique value for its parameter, but this very unlikely to happen here. There's nothing in the shown code that ensures that each execution threads actually gets its own unique thread_id.
Additionally, the original parent execution thread seems to assume that all the execution threads will all finish their job before the parent execution thread reads their results, and writes them out to a file.
Unfortunately, there's no code in the parent execution thread that appears to actually wait for all execution threads to finish. As soon as they're all started, it takes it on faith that they complete instantly, and it reads the partial results, and writes it out to a file:
auto stop = std::chrono::high_resolution_clock::now();
Well, the bad news here is that there's nothing that actually waits for all execution threads to actually stop, at this point. They're still running here. Even if the program manages to avoid crashing, the output results will be incomplete, and mostly junk.
ans[data[i][j].time - 1]
It appears that the value of .time here was originally read from the input file. There does not appear to be any bounds checking here. It's possible for this vector/array access to be out of bounds, resulting in an undefined behavior and a likely crash.
Also, another problem with the shown code: There are plenty of calls to new, but only some of those get deleted, resulting in multiple memory leaks. Inspecting the shown code, there is no clear reason to new anything, in the first place.
In conclusion, there are multiple problems with the shown code that result in undefined behavior, and any of them will be the reason for the observed crash. The shown approach is very much error-prone, and will require much more substantial work, and proper multi-threading support, and inter-thread sequencing, in order to get the sequence of all events happen in the correct order, across all the execution threads.

c++, speeding up a program that compares two lines of arrays and returns the ones that re in the first, but not the second

So i have 2 lines of arrays. First line is M, second line is N.
On the first line the user inputs 2 digits, first for the length of M, and second for the length of N.
On the second line user inputs M, on the third - N. All i want is to display what elements of N are not contained in m, but in ascending order.
Here's an example:
7 5
3.12 7.96 3.51 4.77 10.12 1.11 9.80
10.12 3.51 3.12 9.80 4.77
Output:
1.11 7.96
And here is my attempt at the program:
#include <stdio.h>
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include <vector>
#include <algorithm>
using namespace std;
int ifexists(double z[], int u, int v)
{
int i;
if (u == 0)
return 0;
for (i = 0; i <= u; i++)
if (z[i] == v)
return (1);
return (0);
}
void main()
{
double bills[100], paid[100], result[100];
int m, n;
int i, j, k;
cin >> m >> n;
if (n > m) {
cout << "Wrong input.";
exit(3);
}
for (int i = 0; i < m; i++) {
cin >> bills[i];
}
for (int i = 0; i < n; i++) {
cin >> paid[i];
}
for (i = 0; i < n; i++)
k = 0;
for (i = 0; i < m; i++) {
for (j = 0; j < n; j++) {
if (bills[i] == paid[j]) {
break;
}
}
if (j == n) {
if (!ifexists(result, k, bills[i])) {
result[k] = bills[i];
k++;
}
}
}
for (i = 0; i < k; i++)
cout << result[i] << " ";
}
The output i'm getting is almost correct - 7.96 1.11. Basically in reverse order. How can i flip this around? Also, chances are my report is too slow. Is there a way to increase the speed?
You can use std::set_difference:
std::sort(bills, bills + m);
std::sort(paid, paid + n);
auto end = std::set_difference(bills, bills + m, paid, paid + n, result);
for (auto it = result; it != end; ++it) {
std::cout << *it << " ";
}

Program crashes after checking index at array

Please note: I am not sure if this fits here, if not, please move to the proper forum.
So I have a progrmam that tries to solve th Traveling Salesman Problem, TSP for short.
My code seems to run fine until I try to use 33810 cities, in which the program crashes after trying to access the position costs[69378120], it simply stops responding and end soon after.
I am trying the folowing code:
#include <iostream>
#include <stdlib.h>
#include <malloc.h>
#include <fstream>
#include <math.h>
#include <vector>
#include <limits>
using namespace std;
typedef long long int itype;
int main(int argc, char *argv[]) {
itype n;
ifstream fenter;
fenter.open(argv[1]);
ofstream fexit;
fexit.open(argv[2]);
fenter>> n;
double *x;
double *y;
x = (double*) malloc(sizeof(double)*n);
y = (double*) malloc(sizeof(double)*n);
cout<<"N : "<<n<<endl;
for (int p = 0; p < n; p++) {
fenter>> x[p] >> y[p];
}
fenter.close();
int *costs;
costs = (int*) malloc(sizeof(int)*(n*n));
for (int u = 0; u < n; u++) {
for (int v = u+1; v < n; v++) {
itype cost = floor(sqrt(pow(x[u] - x[v], 2) + pow(y[u] - y[v], 2)));
cout<<"U: "<<u<<" V: "<<v<<" COST: "<<cost<<endl;
costs[u*n + v] = cost;
cout<<"POS (u*n + v): "<<(u*n + v)<<endl;
cout<<"POS (v*n + u): "<<(v*n + u)<<endl;
costs[v*n + u] = cost;
}
}
return 0;
}
According with some verifications, the cost array should use 9.14493GB, but Windows only gives 0.277497GB. Then after triying to read costs[69378120], it closes.
For now, I not worried about the efficiency, nor the solution to the TSP, just need to fix this issue. Any clues?
---UPDATE---
Following the sugestions I tried changing a few things. the result is the code below
int main(int argc, char *argv[]) {
int n;
ifstream entrada;
entrada.open(argv[1]);
ofstream saida;
saida.open(argv[2]);
entrada >> n;
vector<double> x(n);
vector<double> y(n);
for (int p = 0; p < n; p++) {
entrada >> x[p] >> y[p];
}
entrada.close();
vector<itype> costs(n*n);
if(costs == NULL){ cout << "Sem memória!" << endl; return -1;}
for (int u = 0; u < n; u++) {
for (int v = u+1; v < n; v++) {
itype cost = floor(sqrt(pow(x[u] - x[v], 2) + pow(y[u] - y[v], 2)));
costs[u*n + v] = cost;
costs[v*n + u] = cost;
}
}
return 0;
}
The problem still persists
If compiling in 32-bit size_t is 32 bit and then
1143116100*4
is larger than the largest 32-bit number hence int overrun.
Compiling in 64-bit
size_t siz = 1143116100;
std::vector<long long> big(siz);
std::cout << big.size() << ", " << big.max_size() << std::endl;
which prints
1143116100, 2305843009213693951
if I change it to
size_t siz = 1024*1143116100;
I get a bad_alloc as my swap disk is not big enough for that.

Bad Access on Sieve

My block of code runs, but whenever I type in input, it returns Thread 1: EXC_BAD_ACCESS (code=1, address=0x4). I'm fairly new to coding, and was wondering what's wrong.
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
int main() {
int x, count = 1;
cin >> x;
vector<int> sieve;
fill(sieve.begin(), sieve.begin()+x-1, 1);
while (count <= x) {
for (int i = count+1; i <= x; i++) {
if (sieve[i-1] == 1) {
count = i;
break;
}
}
for (int i = count*count; i < x; i+=count) {
sieve[i-1] = 0;
}
}
for (int i = 0; i < x-1; i++) {
if (sieve[i] == 1) {
cout << i+1 << endl;
}
}
}
You need to allocate space for your sieve. So you might want vector<int> sieve(x). Or, you can even do vector<int> sieve(x, 1), which will allocate space for x ints and fill them all with 1s already, so you won't need the fill afterwards.

Why does my program give a "segmentation fault" (core dumped) error after running

I've to create a prime checker using semaphores. The code executes till the "Finding Primes from" part and after that crashes saying "Segmentation Fault (Core Dumped)". After searching about this I understand that it happens when the program tries to access a part of memory that isn't available; but I don't understand it in my code. Please do a take a look and thank you!
#include <QThread>
#include <QSemaphore>
#include <QMutex>
#include <iostream>
#include <stdlib.h>
#include <cmath>
#include <vector>
using namespace std;
#define TOTALSPACE 50
vector<int> buffer(TOTALSPACE);
QSemaphore space(TOTALSPACE), avail;
QMutex l;
int prime_from, prime_to, num_threads;
int total = 0, cnumber = 0;
int in = 0, out = 0;
bool b = false;
//-----Generator------
class Generator : public QThread
{
private:
int strt;
int end;
public:
Generator(int a, int b)
{
strt = a;
end = b;
cnumber = strt;
}
void run()
{
while (cnumber < end)
{
space.acquire();
cnumber++;
buffer[in] = cnumber;
in = (in + 1) % TOTALSPACE;
avail.release();
}
b = true;
for (int i = 0; i < num_threads; i++)
{
space.acquire();
buffer[in] = -1;
in = (in + 1) % TOTALSPACE;
avail.release();
}
}
};
//-----------Checker----------
class Checker : public QThread
{
private:
int number;
public:
Checker() {}
void run();
};
void Checker::run()
{
while (1)
{
avail.acquire();
l.lock();
number = buffer[out];
if (number == -1)
{
l.unlock();
break;
}
bool isPrime = false;
for (int i = 2; i <= sqrt(number); i++)
{
if (number%i == 0)
{
isPrime = true;
break;
}
}
out = (out + 1) % TOTALSPACE;
if (isPrime == false)
{
total++;
}
l.unlock();
space.release();
}
}
//-------------Main---------
int main(int argc, char *argv[])
{
num_threads = atoi(argv[1]);
prime_from = atoi(argv[2]);
prime_to = atoi(argv[3]);
cout << " Number of Threads = " << num_threads << endl;
cout << " Primes checking from " << prime_from << " to " << prime_to << endl;
Generator gen(prime_from, prime_to);
gen.start();
Checker* thr[num_threads];
for (int i = 1; i < num_threads; i++)
{
thr[i] = new Checker();
thr[i]->start();
}
gen.wait();
for (int i = 0; i < num_threads; i++)
{
thr[i]->wait();
}
cout << "Total Primes: " << total << endl;
return 0;
}
There's a couple of things that could cause this. For one, you never check whether there's enough parameters supplied or not (argc>3). So you could pass invalid pointers to atoi
But far more likely is that you did not initialize thr[0] because you start your initialization loop with for (int i = 1; but you access thr[0] in the loop for synchronization because you start it with or (int i = 0;.
In addition it is noteworthy that you are using Variable Length Arrays when you do Checker* thr[num_threads]; because num_threads is not a compile-time constant. That feature is not part of the C++ standard at this time (not in C++14). So, if you want to make your program portable you can do Checker** thr = new Checker*[num_threads]; and delete [] thr; at the end if you want to be diligent (and not use smart pointers).