英文:
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 <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");
}
}
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)->size;
for (int j = 0; j < size; j++)
{
for (int i = 0; i < size; i++)
{
((struct args *)input)->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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论