使用void表达式无效(C)

时间:2016-03-25 07:20:23

标签: c multithreading pthreads syntax-error void-pointers

我在这里看了很多关于我的问题的答案,但没有人回答我面临的问题。

我正在用C编写一个多线程程序来执行矩阵乘法来评估系统性能。

目前我只是尝试在传递几个变量时启动单个线程。

这是我的代码

pthread_t *thread = (pthread_t *) malloc(sizeof(pthread_t));

int a = malloc(sizeof(int));
int b = malloc(sizeof(int));
a = 0;
b = size;
void **args = (void **) malloc(2 * sizeof(void *));
args[0] = (void *)a;
args[1] = (void *)b;

pthread_create(&thread[0], NULL, matrixMath, &args);

matrixMath方法:

void* matrixMath(void* args) {
  int start = *((int *)args[0]);
  int end = *((int *)args[1]);

  printf("Start: %d, End: %d\n", start, end);

  return NULL;
}

每当我尝试编译时,我在“int start”和“int end”声明中都得到“无效使用void表达式”。我基于the discussion found here这些行。有什么帮助吗?

2 个答案:

答案 0 :(得分:2)

由于argsvoid *,因此您无法取消引用它,但args[0]会在应用(int *)强制转换之前尝试取消引用它。因此,您需要重新表示,以便在取消引用之前将void *转换为int *

int start = ((int *)args)[0];
int end   = ((int *)args)[1];

或者(但等效地):

int *array = (int *)args;  // You could skip the cast in C
int start  = args[0];
int end    = args[1];

我对&args的调用中的pthread_create()也不相信。这会将void ***传递给线程代码。我认为你需要更像这样的东西,它有许多优点,包括更简单:

pthread_t thread;
int *a = malloc(2 * sizeof(int));
a[0] = 0;
a[1] = size;

pthread_create(&thread, NULL, matrixMath, a);

你甚至可以使用:

pthread_t thread;
int a[] = { 0, size };
pthread_create(&thread, NULL, matrixMath, a);

答案 1 :(得分:1)

我将使用struct演示替代方法。随着时间的推移,这种替代方法更容易编码和维护。

您的代码存在一些可能导致编译器和运行时错误的问题,以下是一些应该指向正确路径的示例:

  1. 您的int作业未执行您可能想要或打算执行的任务。

    你的代码将指针地址的数值赋给一个整数,可能由于可变的大小差异而截断数据......你可能想要的是存储指向int的指针。

    您写道:

    int a = malloc(sizeof(int));
    int b = malloc(sizeof(int));
    

    你可能想写:

    int * a = malloc(sizeof(int));
    int * b = malloc(sizeof(int));
    
  2. 您的代码将void *视为void **(或int *),而不使用任何广告...

    您写道:

    int start = *((int *)args[0]);
    int end   = ((int *)args)[1];
    

    你可能想写:

    int start = ( (int *)args )[0];
    int end   = ( (int *)args )[1];
    
  3. 您的代码执行malloc三(3)次,但从不调用free(您有内存泄漏)。

  4. 如果您定义一个struct来包含您想要的数据并移动"将会更容易。 (或与之分享)。

    例如,以下 未经测试的 代码可能不起作用,但它清楚地显示了如何使用struct进行数据传输的概念更易于管理,维护和更新。它还需要较少的malloc调用,使内存管理更容易。

    struct ThreadData {
       int start;
       int end;
    };
    
    void * thread_task(void *);
    
    int main(void) {
       struct ThreadData * data = malloc(sizeof(*data));
       data->start = 0;
       data->end = 0; // = size;
       pthread_t thr;
       pthread_create(&thr, NULL, thread_task, data);
       // ... do whatever.
       // ... remember to join thread
    }
    
    void * thread_task(void * _data) {
       struct ThreadData * data = _data;
       printf("Start: %d, End: %d\n", data->start, data->end);
       // remember to free the memory when you're done.
       free(data);
       return NULL;
    }
    

    这种方法更容易编码和维护。此外,当您需要为新线程添加数据时,它很简单 - 只需更新结构。

    您甚至可以将复杂的返回值放回结构中的占位符中,从而允许线程执行更复杂的任务(请记住避免让多个线程写入同一个struct字段)。 / p>