Segmentation fault at std::thread - c++

typedef struct _ppm_struct* ppm_struct;
typedef unsigned char ppm_subpixel;
typedef ppm_subpixel (*ppm_pixel_func)(ppm_subpixel);
struct ppm_pixel {
ppm_subpixel red;
ppm_subpixel green;
ppm_subpixel blue;
};
struct _ppm_struct {
unsigned int width;
unsigned int height;
unsigned int max_color;
ppm_pixel *firstpixel;
};
So I have this function call:
void pppm_color_pixel(ppm_struct p, ppm_struct out, ppm_pixel_func func, int threads) {
//ppm_pixel_func func2 = &inverse_pixel;
unsigned int w = p->width;
unsigned int h = p->height;
ppm_pixel *iterator = p->firstpixel;
std::thread th[threads];
long long total_pixels = w*h;
unsigned int count_for_thread = total_pixels/threads;
for(int j = 0; j<threads; ++j) {
th[j] = std::thread(pppm_color_chunk_pixel,func, *iterator,count_for_thread);
iterator = &iterator[count_for_thread];
}
for(int j = 0; j<threads; ++j) {
th[j].join();
}
The next two function: funct is inverse subpixel
ppm_subpixel inverse_subpixel(ppm_subpixel subpixel) {
subpixel = 255- subpixel;
return subpixel;
}
void pppm_color_chunk_pixel(ppm_pixel_func func, ppm_pixel start_pixel, unsigned int count) {
ppm_pixel *iterator = &start_pixel;
for(unsigned int i = 0; i< count; ++i) {
iterator[i].red = func(iterator[i].red);
iterator[i].green = func(iterator[i].green);
iterator[i].blue = func(iterator[i].blue);
}
}
The main:
pppm_color_pixel(p,out, &inverse_subpixel,pppm_get_max_cores());
The problem is that when I run this it shows me a segmentation fault. This happen on this line:
iterator[i].green = func(iterator[i].green);
What I really don't understand is that i = 2 or more when this happens. It doesn't crash from the first time. Even if I try to call only a single thread the result is the same.

pppm_color_chunk_pixel accepts a copy of ppm_pixel. Since it is copied by value, passing *iterator to it will cause only one element to be copied. Iterating over anything after &start_pixel will fail.
Since std::thread doesn't pass objects by reference, you also need a reference-wrapper for this.
void pppm_color_chunk_pixel(ppm_pixel_func func, ppm_pixel& start_pixel, unsigned int count) {
ppm_pixel* iterator = &start_pixel;
for (unsigned int i = 0; i < count; ++i) {
iterator[i].red = func(iterator[i].red);
iterator[i].green = func(iterator[i].green);
iterator[i].blue = func(iterator[i].blue);
}
Calling it:
for (int j = 0; j < threads; ++j) {
th[j] = std::thread(pppm_color_chunk_pixel, func, std::ref(*iterator), count_for_thread);
iterator = &iterator[count_for_thread];
}
I have not tested it, but I guess this is your problem.

Related

Initialize C++ struct that contains a fixed size array

Suppose I have a POD C struct as so:
struct Example {
int x;
int y[10];
int yLen;
}
With the following code, the program doesn't compile:
Example test() {
int y[10];
int yLen = 0;
auto len = this->getSomethingLength();
for (int i = 0; i < len; i++) {
y[yLen++] = this->getSomething(i);
}
return Example{ 0, y, yLen };
}
However, doing return {0, {}, 0}; does seem to compile. Problem is, I can't know the size of y until doing some sort of logic ahead of time. Initializing int y[10]{} in test doesn't seem to make a difference. I know this seems like a pretty simple question, but I can't seem to find anything that works.
Declare the structure as a whole instead of its parts and then initialize it:
Example test() {
Example result;
auto len = this->getSomethingLength();
for (result.yLen = 0; result.yLen < len; result.yLen++) {
result.y[result.yLen] = this->getSomething(result.yLen);
}
return result;
}
Declaring y as an int* and allocating memory with new, when the size is known, would be an even better solution.
Declare constructor in Example:
struct Example {
int x;
int y[10];
int yLen;
Example(int xNew, int *yNew, int yLenNew)
{
x = xNew;
yLen = yLenNew;
for (int i = 0; i < yLenNew; i++)
{
y[i] = yNew[i];
}
}
};
And use it like this:
Example test() {
int y[10];
int yLen = 0;
auto len = this->getSomethingLength();
for (int i = 0; i < len; i++) {
y[yLen++] = this->getSomething(i);
}
return Example( 0, y, yLen );
}

How to pass an array of structure by reference for sorting?

In this code , I am creating an array of structure and trying to sort the structure array based on "arr_time" field. I am having problem on how to pass the structure array by reference in function sort_process() .
#include<iostream>
using namespace std;
struct process {
public:
int p_id,arr_time,burst_time,comp_time;
};
void sort_process( process x[],int len)
{
int i,j;
process temp;
for(i=0;i<len;i++)
{
for(j=0;j<len-1;j++)
{
if(x[j].arr_time > x[j+1].arr_time)
{
temp = x[j];
x[j] = x[j+1];
x[j+1] = temp;
}
}
}
}
int main()
{
int n,i=0,j=0,k=0,t=0,flag;
cout<<"\n Enter number of processes : ";
cin>>n;
process p[n];
for(i=0;i<n;i++)
initialize(p[i]);
sort_process(p,n);
return 0;
}
You can simply use std::sort in the header <algorithm>:
std::sort(p, p+n, [](const process & p1, const process & p2){return p1 < p2}); // Will sort p in ascending order
But if you really want to do it manually and pass the array to a function, you can create the function as:
void sort_process(process * x, std::size_t len) // copy the pointer
{
std::sort(x, x+len, [](const process & p1, const process & p2){return p1 < p2;});
}
But passing process x[] as you did is equivalent.
Note: As we refer to an array by the pointer to its first element, what your are passing here is a pointer to the first element too (and not the array).
If you really want to pass it by reference, you can do it as follows:
void sort_process(process * const & x, std::size_t len)
{
std::sort(x, x+len, [](const process & p1, const process & p2){return p1 < p2;});
}
I added a const qualifier to forbid the modification of the pointer as it is not a copy but a reference to the original one
But you don't really gain anything by passing a reference here in my opinion.
Seems like you are afraid of dynamic arrays and pointers. Try this:
#include<iostream>
using namespace std;
struct process
{
int p_id, arr_time, burst_time, comp_time;
void initialize()
{
p_id = arr_time = burst_time = comp_time = 0;
}
process()
{
p_id = arr_time = burst_time = comp_time = 0;
}
~process() {}
};
void sort_process(process*& x, int len)
{
int i, j;
process temp;
for (i = 0; i < len; i++)
{
for (j = 0; j < len - 1; j++)
{
if (x[j].arr_time > x[j + 1].arr_time)
{
temp = x[j];
x[j] = x[j + 1];
x[j + 1] = temp;
}
}
}
}
int main()
{
int n, i = 0, j = 0, k = 0, t = 0, flag;
cout << "\n Enter number of processes : ";
cin >> n;
process* p = new process[n];
for (i = 0; i < n; i++)
p[i].initialize();
sort_process(p, n);
for (i = 0; i < n; i++)
p[i].~process();
delete[] p; p = 0;
return 0;
}

vectorize non aligned data in a struct method

I have this simple struct:
struct cbt
{
vector<vector<int>> tree;
int depth;
int data;
cbt(int max_size) // just initializes tree
{
depth = (int) log2(max_size);
unsigned int l;
for(int i = 0; i <= depth; i++)
{
l = (unsigned int) pow(2,i);
tree.push_back(vector<int>(l,0));
}
}
inline void update(int pos, int value)
{
int diff = value - data;
int p = pos>>1;
for(int i = depth; i >= 0; i--)
{
tree[i][p] += diff;
p = p>>1;
}
}
};
Is there any way to vectorize the loop in the update() function even thought the data is not aligned?
In my code the update() function is called billions of times and so I was hoping to make it as fast as possible.

int vs. BGRA union of the same size produces different results

Can someone explain the difference between the three below functions?
typedef union
{
std::uint8_t B, G, R, A;
std::uint32_t Colour;
} BGRA;
1st:
void Image::process_pixels(void* out, void* in)
{
unsigned int i, j;
BGRA* pOut = (BGRA*)out;
unsigned char* pIn = (unsigned char*)in;
for (i = 0; i < height; ++i)
{
for (j = 0; j < width; ++j)
{
pOut->B = *(pIn++);
pOut->G = *(pIn++);
pOut->R = *(pIn++);
pOut->A = *(pIn++);
++pOut;
}
}
}
2nd:
void Image::process_pixels(void* out, void* in)
{
unsigned int i, j;
unsigned int* pOut = (unsigned int*)out;
unsigned int* pIn = (unsigned int*)in;
for (i = 0; i < height; ++i)
{
for (j = 0; j < width; ++j)
{
*pOut++ = *pIn++
}
}
}
3rd:
void Image::process_pixels(void* out, void* in)
{
unsigned int i, j;
BGRA* pOut = (BGRA*)out;
unsigned char* pIn = (unsigned char*)in;
for (i = 0; i < height; ++i)
{
for (j = 0; j < width; ++j)
{
memcpy(pOut, pIn, sizeof(int));
++pOut;
pIn += sizeof(int);
}
}
}
If I use the second or third implementation, the code works fine. Images render properly. However, if I use the first implementation, nothing renders correctly.
I can guarantee that sizeof(BGRA) = sizeof(int). I can guarantee BGRA format for the pixels. Yet somehow I get different results..
I can't see for the life of me, the difference between the first and the last two implementations. Any ideas?
typedef union
{
std::uint8_t B, G, R, A;
std::uint32_t Colour;
} BGRA;
Here B, G, R and A are 4 elements that share the same address.
You should enclose B, G, R and A inside a struct like
typedef union
{
struct {
std::uint8_t B, G, R, A;
} Components;
std::uint32_t Colour;
} BGRA;
This union has five members. You seem to think it has only two.

Use function from another class or struct in a function within this class

I am creating a hash table and need to have this chained hash table tested with different hash functions.
I have hash structs such as
struct Hasher {
virtual int hash(std::string s, int N) = 0;
};
struct SumHasher : Hasher {
int hash(std::string s, int N){
int result = 0;
for (int i=0; i<s.size(); ++i)
result += s[i];
return int (std::abs((int)result)) % N;
}
};
struct ProdHasher : Hasher {
int hash(std::string s, int N) {
int result = 1;
for (int i=0; i<s.size(); ++i)
result *= s[i];
return int (std::abs((int)result)) % N;
}
};
struct ShiftHasher : Hasher {
int hash(std::string s, int N){
const int shift = 6; unsigned z = 0;
const int mask = ~z >> (32-shift); // lower 6 bits on
int result = 0;
for (int i = 0; i < s.length(); i++)
result = (result << shift) | (s[i] & mask);
return int (std::abs((int)result)) % N;
}
};
Now how can I use this functions within the Hashtable class by creating a struct hash type then passing that object to the constructor
class ChainedHashTable
{
ListNode **T; // array of linked lists
int capacity;
public:
Hasher *myhash;
int info;
ChainedHashTable(int numberOfChains, Hasher *myHasher){
myhash = hasher;
capacity = numberOfChains;
T = new ListNode* [capacity];
for (int i=0; i<capacity; ++i)
T[i] = NULL;
}
.......
void ChainedHashTable::insert(std::string key, int info){
int h = myhash::hash(key, capacity);
T[h] = ListNode::make(key, info, T[h]);
}
you should use:
myhash->hash(key, capacity)