C ++:pthread_create上的分段错误

时间:2017-11-02 04:44:56

标签: c++ opencv pthreads

我对C一般来说相对较新,我在使用pthread时尝试制作小型图像滤镜。在使用指针和引用几个小时之后,它会通过编译器,但后来我遇到了分段错误,代码如下:

#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);
}

我使用GDB找到了罪魁祸首,并设法在第107行找到它:

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

此时,我试图到处寻找解决方案,我尝试了以下方法:

  • 改变我定义结构的方式,让它接收指针,我后来发现它没有用。
  • 更改传递参数的方式(例如添加或删除 (*void)它似乎是正确的),最终导致了更大的混乱 错误或最后只是相同的错误。

此外,在尝试阅读gdb bt输出时,对这种语言不熟悉并不能帮助我:

#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

我的一部分想要认为问题与optimized out部分有关,但查找它不会产生任何结果,或者至少,我可能看起来不正确。

关于我在这里做错了什么的任何想法?我非常感谢你的帮助!

1 个答案:

答案 0 :(得分:3)

中使用之前,您尚未初始化t
 pthread_create(&threads[t], NULL, parallel_processing_task, (void *)&input);

因此,这可能导致未定义的行为,因为t可能有任何可能使&threads[t]访问无效内存的值