如何在C中将动态大小的结构数组作为多线程函数的参数传递。

huangapple go评论78阅读模式
英文:

How to create dynamic sized array of struct as parameter of multithread function in C

问题

I want to fill 2d array of struct with all 0. Firstly, I defined size of 2d array with define macro. As follows:

> #define VECLEN 4

I have struct as follows:

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

However, I want to get the size of my 2d array from user but I couldn't dynamically give the size of 2d array.

I use multithread functionality with pthread_create using 2 threads. I have to call fill function twice with multithread. When I fill the input array with defined size(4), I can easily get desired output as follows:

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

However, I got weird result when I want to fill a 6*6 array as follows:

     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       

Here is my code:

#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");
  }
}
英文:

I want to fill 2d array of struct with all 0. Firstly, I defined size of 2d array with define macro. As follows:

> #define VECLEN 4

I have struct as follows:

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

However, I want to get the size of my 2d array from user but I couldn't dynamically give the size of 2d array.

I use multithread functionality with pthread_create using 2 threads. I have to call fill function twice with multithread. When I fill the input array with defined size(4), I can easily get desired output as follows:

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

However, I got weird result, when I want to fill 6*6 array as follows:

     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       

Here is my code:

#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");
  }
}

答案1

得分: 2

你可以这样使用malloc和可变修改类型(如果支持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("请输入大小: ");
  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);

这是因为存在对齐问题。

英文:

You can use malloc and Variably Modified types as follows (if you support C99 or above but I've also shown below the alternatives as well):

The issue with your code is that you are not allocating enough storage and additionally your array type (specifically the first dimension) is fixed.

#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;pthread.h&gt;

pthread_mutex_t myMutex;

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

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

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

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

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

  pthread_t threads[2];

  pthread_mutex_init(&amp;myMutex, NULL);

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

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

  pthread_mutex_destroy(&amp;myMutex);

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

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

Variably Modified type dimensions are calculated at runtime. We also use a flexible array member at the end of the structure and add the size of our variably modified array to the malloc call.

The benefit of this approach is that the fill function works as expected without modification. The alternative implementation is as follows:

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

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

As well as the malloc call:

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

For the flexible array member - the alternative approach would be:

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

With the following malloc:

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

The above is because of alignment issues present otherwise.

huangapple
  • 本文由 发表于 2023年5月11日 03:40:00
  • 转载请务必保留本文链接:https://go.coder-hub.com/76222050.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定