如何在C中创建动态大小的结构数组作为多线程函数的参数

z6psavjg  于 2023-05-16  发布在  其他
关注(0)|答案(1)|浏览(143)

我想用全0填充结构体的2d数组。首先,我用define宏定义了2d数组的大小。具体如下:

define VECLEN 4

我有如下结构:

struct args
{
  int size;
  int array[VECLEN][VECLEN];
};

然而,我想从用户那里得到我的2d数组的大小,但我不能动态地给予2d数组的大小。
我使用多线程功能,pthread_create使用2个线程。我必须用多线程调用填充函数两次。当我用定义的size(4)填充输入数组时,我可以很容易地得到所需的输出,如下所示:

0       0       0       0
 0       0       0       0
 0       0       0       0
 0       0       0       0

然而,我得到了奇怪的结果,当我想填充6*6数组如下:

0       0       0       0       0       0
     0       0       0       0       0       0
     0       0       0       0       0       0
     0       0       0       0       0       0
     0       0       0       154148873       537473056       824183088
     537473056       825636144       892483616       825635638       537474100

下面是我的代码:

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

#define VECLEN 4
pthread_mutex_t myMutex;

struct args
{
  int size;
  int array[VECLEN][VECLEN];
};

void fill(void *input)
{
   int size = ((struct args *)input)->size;

   for (int j = 0; j < size; j++)
   {
      for (int i = 0; i < size; i++)
      {
        ((struct args *)input)->array[i][j] = 0;
      }
   }
}

int main()
{
  struct args *arguments = (struct args *)malloc(sizeof(struct args));
  int number;
  printf("please enter the size : ");
  scanf("%d", &number);
  arguments->size = number;

  pthread_t threads[2];

  pthread_mutex_init(&myMutex, NULL);

  for (int i = 0; i < 2; i++)
    pthread_create(&threads[i], NULL, fill, (void *)arguments);

  for (int i = 0; i < 2; i++)
    pthread_join(threads[i], NULL);

  pthread_mutex_destroy(&myMutex);

  for (int row = 0; row < number; ++row)
  {
    for (int col = 0; col < number; ++col)
        printf("\t %d", arguments->array[row][col]);
    printf("\n");
  }
}
z9ju0rcb

z9ju0rcb1#

您可以使用malloc和Variably Modified类型,如下所示(如果您支持C99或更高版本,但我也在下面显示了替代品):
代码的问题是没有分配足够的存储空间,而且数组类型(特别是第一维)是固定的。

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

pthread_mutex_t myMutex;

struct args
{
  int size;
  int array[];
};

void fill(void *input)
{
   int size = ((struct args *)input)->size;

   int (*parray)[size] = ((struct args *)input)->array;

   for (int j = 0; j < size; j++)
   {
      for (int i = 0; i < size; i++)
      {
        parray[i][j] = 0;
      }
   }
}

int main()
{
  struct args *arguments;
  int number;
  printf("please enter the size : ");
  scanf("%d", &number);
  arguments = malloc(sizeof(struct args) + sizeof(int[number][number]));
  arguments->size = number;

  pthread_t threads[2];

  pthread_mutex_init(&myMutex, NULL);

  for (int i = 0; i < 2; i++)
    pthread_create(&threads[i], NULL, fill, (void *)arguments);

  for (int i = 0; i < 2; i++)
    pthread_join(threads[i], NULL);

  pthread_mutex_destroy(&myMutex);

  int (*parray)[number] = arguments->array;

  for (int row = 0; row < number; ++row)
  {
    for (int col = 0; col < number; ++col)
        printf("\t %d", parray[row][col]);
    printf("\n");
  }
}

可变修改类型标注在运行时计算。我们还在结构的末尾使用灵活的数组成员,并将可变修改的数组的大小添加到malloc调用中。
这种方法的好处是fill函数可以按预期工作,无需修改。替代实施方式如下:

void fill(void *input)
{
   int size = ((struct args *)input)->size;

   for (int j = 0; j < size; j++)
   {
      for (int i = 0; i < size; i++)
      {
        ((struct args *)input)->array[i * size + j] = 0;
      }
   }
}

以及malloc调用:

arguments = malloc(sizeof(struct args) + sizeof(int) * number * number);

对于柔性阵列构件,替代方法将是:

struct args
{
  int size;
  int array[1];
};

使用以下malloc:

arguments = malloc(offsetof(struct args, array) + sizeof(int) * number * number);

以上是因为以其他方式存在的对准问题。

相关问题