在平行的mandelbrot算法中与C中的Memcpy分割故障:如何在结构中使用指针



目标是用顺序的mandelbrot算法编写并行化。我的数据类型和指针遇到了一些问题。

这就是我的主要c的样子:

int main(int argc, char **argv)
{
    /****
    Here are initializations and some for my question irrelevant code...
    *****/
    unsigned char (*image)[x_resolution][3];
    image = malloc(x_resolution * y_resolution * sizeof(char[3]));
    // compute mandelbrot   
    mandelbrot_draw(x_resolution, y_resolution, max_iter, view_x0, view_x1,
    view_y0, view_y1, x_stepsize, y_stepsize, palette_shift, image, 
    num_threads);
    free(image);
}

我正在努力的第一件事是行unsigned char (*image)[x_resolution][3];我理解的方式是,我正在用*image创建指针。我也知道在处理数组中使用括号。但是我并不真正了解我得到的数据类型。

然后我的平行算法以这样的启动:

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <complex.h>
#include <pthread.h>
#include "mandelbrot.h"
struct pthread_args_struct
{
    int x_resolution;
    int y_resolution_lower_boundary;
    int y_resolution_upper_boundary;
    int max_iter;
    double view_x0;
    double view_y1;
    double x_stepsize;
    double y_stepsize;
    int palette_shift;
    unsigned char** img;
};

我需要这个结构,因为我需要将参数传递给pthreads_create,而且此函数只能获取一个输入参数。我研究了您如何处理结构内的指针,并像这里所建议的那样:在struct

中存储和访问2D阵列

我在代码中还具有以下功能:

void mandelbrot_draw(int x_resolution, int y_resolution, int max_iter,
                double view_x0, double view_x1, double view_y0, double 
                view_y1, double x_stepsize, double y_stepsize,
                int palette_shift, unsigned char (*img)[x_resolution][3],
                int num_threads) {
    //I split the image into rows 
    //  and let each thread calculate the pixels for one row
    int y_resolution_thread[num_threads+1]; 
    for (int t = 0; t < num_threads; t++)
    {       
        y_resolution_thread[t] = t*(y_resolution/num_threads);
        y_resolution_thread[num_threads] = y_resolution;
    }
    //allocate pthreads space and space for struct
    pthread_t *threads = (pthread_t*) malloc (num_threads*sizeof(pthread_t));
    struct pthread_args_struct* args = (struct pthread_args_struct*) malloc 
    (num_threads*sizeof(struct pthread_args_struct));
    //create threads, start mandelbrot_draw_row in parallel
    for(int i = 0; i < num_threads; ++i) {
        args[i].y_resolution_lower_boundary = y_resolution_thread[i];
        args[i].y_resolution_upper_boundary = y_resolution_thread[i+1];         
        args[i].x_resolution = x_resolution;
        args[i].max_iter = max_iter;
        args[i].view_x0 = view_x0;
        args[i].view_y1 = view_y1;
        args[i].x_stepsize = x_stepsize;
        args[i].y_stepsize = y_stepsize;
        args[i].palette_shift = palette_shift;
        memcpy(&args[i].img, img, sizeof(img));
        //create thread and pass arguments
        pthread_create (&threads[i] , NULL, mandelbrot_draw_row, args+i);
    }
    //wait for finish and join
    for (int i = 0; i < num_threads; ++i){
        pthread_join(threads[i], (void*)&img);
    }
    free(threads); free(args);
    return((void*) &img);
}
void* mandelbrot_draw_row (void* args){
    struct pthread_args_struct* arg = (struct pthread_args_struct*) args;
    arg->img = malloc(sizeof(arg->img));
    int k;
    for (int i = arg->y_resolution_lower_boundary; i < arg-> 
    y_resolution_upper_boundary; i++)
    {
        for (int j = 0; j < arg->x_resolution; j++)
        {
            k = 0;
            //do some calculations here
            if (k == arg->max_iter)
            {   
                memcpy(&args->img[i][j], "", 3); <- here I get a 
                                                         segmentation fault
            }
            else
            {
                int index = (k + arg->palette_shift)
                        % (sizeof(colors) / sizeof(colors[0])); 
                memcpy(&args->img[i][j], colors[index], 3);
            }
        }
    }
    return(void*) &arg->img;
}

这是我的主要问题:我在memcpy(&args->img[i][j], "", 3);中得到了分段故障。我认为我在这里的指针确实做错了什么,但是我真的不明白我应该做的事情。

您的问题是您的图像点指向一个单个大3D数组。在内存中,这是一大堆值。我试图绘制图片以表示下面的3D阵列。

,但是您正在尝试将其像1D数组的指针到1D数组一样使用。无论哪种方式切成薄片,这都可能无法使用,因为您的数组一开始就没有指针。

您应该更改类型:

unsigned char** img;

使其与main中的一个:

中的一个匹配
unsigned char (*image)[x_resolution][3];

然后替换以下:

memcpy(&args[i].img, img, sizeof(img));

仅:

args[i].img = img;

我看到您正在使用Memcpy,因为编译器抱怨您试图将指针分配给其他类型的指针。编译器抱怨是有原因的。

最新更新