c - 并行 mandelbrot 算法中 C 中 memcpy 的段错误 : How to use pointers in a struct?

标签 c pointers struct pthreads mandelbrot

目标是从顺序 mandelbrot 算法中编写并行化。我的数据类型和指针有一些问题。

这是我的 main.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,而这个函数只能获取一个参数作为输入。我研究了如何处理结构中的指针,并按照此处的建议进行操作:Storing and Accessing a 2D Array in a Struct

我的代码中还有以下功能:

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], "\0\0\0", 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], "\0\0\0", 3); 中遇到段错误。我认为我在这里用指针做了一些非常错误的事情,但我无法真正理解我应该做什么。

最佳答案

您的问题是您的图像指针指向一个单一的大型 3D 阵列。它是内存中彼此相邻的一大堆值。我试着画了一张图来表示下面的 3D 数组。

但随后您尝试将其用作指向一维数组的一维指针数组。无论以哪种方式切片,这都不可能起作用,因为您的数组中没有指针开始。

你应该改变类型:

unsigned char** img;

以便它与 main 中的匹配:

unsigned char (*image)[x_resolution][3];

然后替换为:

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

只有:

args[i].img = img;

我看到您正在使用 memcpy,因为编译器提示您试图将指针分配给不同类型的指针。编译器提示是有原因的。

关于c - 并行 mandelbrot 算法中 C 中 memcpy 的段错误 : How to use pointers in a struct?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50052662/

相关文章:

go - 结构在 for 循环初始化器中

C++ 将结构字符串保存到文本文件中

c - 如何在 C 中解析带引号的 .csv 文件

c++ - 嵌套函数调用快还是不快?

c - 按位与表达式中操作数的可能值

c - 从不兼容指针类型/解引用指针到不完整类型的赋值

ios - 如何使用json解析选择所有 TableView 行并获取所有行的id?

c - 当提示用户输入 CELSIUS 值时,为什么我的 CELSIUS 到 RANKINE 转换失败?

侧信道攻击的 C 时序内存访问

在 C 中连接两个 const char *