简体   繁体   中英

C++: Segmentation fault on pthread_create

I'm relatively new to C in general and I'm trying to make a small image filter while using pthreads. After a few hours of playing around with pointers and references, it goes through the compiler but then I get a segmentation fault, the code is the following:

#include <iostream>
#include <opencv2/core.hpp>
#include <opencv2/imgcodecs.hpp>

using namespace std;
using namespace cv;

#define WIDTH 3
#define HEIGHT 4

#define NUM_THREADS 4

struct readThreadParams{
    Mat img;
    Mat out;
    int yStart;
    int xEnd;
    int yEnd;
    int xRad;
    int yRad;
};

//Find average of all pixels in WXH area 
uchar getAverage(Mat &img, Mat &out, const float x1, const float y1, const int xRad, const int yRad){
    //x1, y1: Pixel position being checked. xRad, yRad: how many pixels are being checked in x and y, relative to starting point.

    uchar blue;
    uchar green;
    uchar red;
    Vec3b outColor;
    for (int c = 0; c < xRad; c++){
        for (int r = 0; r < yRad; r++){
            Vec3b intensity = img.at<Vec3b>(r, c);
            blue =+ intensity.val[0];
            green =+ intensity.val[1];
            red =+ intensity.val[2];
        }
    }
    outColor[0] = (blue/(xRad*yRad*4));
    outColor[1] = (green/(xRad*yRad*4));
    outColor[2] = (red/(xRad*yRad*4));
    for (int c = 0; c< xRad; c++){
        for (int r = 0; r< yRad; r++)
            out.at<Vec3b>(Point(c, r)) = outColor;
    }

}


void* parallel_processing_task(void * param){
    //This is what each thread should do:

    struct readThreadParams *input = (struct readThreadParams*)param;

    Mat img = input->img;
    Mat out = input->out;
    const float yStart = input->yStart;
    const float xEnd = input->xEnd;
    const float yEnd = input->yEnd;
    const float xRad = input->xRad;
    const float yRad = input->yRad;

    for (int c = 0; c < xEnd; c + xRad){
        for (int r=yStart; r < yEnd; r + yRad){
            getAverage(img, out, c, r, xRad, yRad);
        }
    }
}



int main(int argc, char *argv[]){

    //prepare variables
    pthread_t threads[NUM_THREADS];
    void* return_status;
    struct readThreadParams input;
    int t;

    Mat img = imread("image.jpg", IMREAD_COLOR);
    int ROWS = img.rows;
    int COLS = img.cols;
    Mat out(ROWS, COLS, CV_8UC3);
    input.img = img;
    input.out = out;
    input.xEnd = COLS;
    input.xRad = WIDTH;
    input.yRad = HEIGHT;

    double t2 = (double) getTickCount();


    for (int r = 0; r<ROWS ; ceil(ROWS/NUM_THREADS)){
            input.yStart = r;
            input.yEnd = r + ceil(ROWS/NUM_THREADS);
            pthread_create(&threads[t], NULL, parallel_processing_task, (void *)&input);            
    }
    for(t=0; t<NUM_THREADS; t++){
                pthread_join(threads[t], &return_status);
    }

    t2 = ((double) getTickCount() - t2) / getTickFrequency();

    //print execution time
    cout << "Execution time: " << t2 << " s" << endl;

    //result image
    imwrite("output.png", out);

    return(0);
}

I used GDB to find the culprit and managed to get as far as finding out it's on line 107:

pthread_create(&threads[t], NULL, parallel_processing_task, (void *)&input);

At this point, I tried going all over the place to find solutions, I tried the following:

  • Changing the way I defined the struct, making it receive pointers, which I later found out didn't work.
  • Changing the way I pass arguments (such as adding or removing (*void) where it seemed proper), which ended up in a bigger mess of errors or simply the same error at the end.

Furthermore, being new to this language doesn't really help me out when trying to read the gdb bt output:

#0__pthread_create_2_1(newthread=optimized out>, attr=<optimized out>, start_routine=<optimized out>, arg=<optimized out>) at pthread_create.c:601
#1 0x00011a00 in main(argc=1, argv=0x7efff394) at file.cpp:107

A part of me wants to think the problem is related to the optimized out parts, but looking it up yields no results, or at least, I may not be looking properly.

Any thoughts as to what I may be doing wrong here? I would very much appreciate the help!

You have not initialised t prior to using it in

 pthread_create(&threads[t], NULL, parallel_processing_task, (void *)&input);

So this is likely to lead to undefined behaviour as t may be having any value that could make &threads[t] access invalid memory

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM