目标是从顺序 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/