C语言中如何创建动态大小的结构体数组作为多线程函数参数
问题分析与解决
核心问题
- 固定数组越界:结构体中
array是通过宏定义的固定4×4数组,当用户输入大于4的尺寸时,程序会越界访问/修改内存,破坏堆上其他区域的数据,最终出现乱码。 - 多线程无同步:两个线程同时对同一数组执行写操作,即使数组大小正确,也存在竞争风险(虽写0操作看似无害,但不符合多线程编程规范,后续修改为其他逻辑会引发问题)。
解决方案
1. 动态分配二维数组
将结构体中的固定数组改为指针类型,运行时根据用户输入的尺寸动态分配内存,彻底避免越界问题。
2. 任务拆分实现无锁同步
拆分数组填充任务,让每个线程负责不同的行区间,线程间操作无重叠,无需互斥锁即可保证安全,同时提升效率。
修改后的完整代码
#include <stdio.h> #include <stdlib.h> #include <pthread.h> // 修改结构体:使用指针存储动态二维数组,新增任务区间字段 struct args { int size; int **array; int start_row; int end_row; }; // 线程函数:填充指定行区间的数组为0 void *fill(void *input) { struct args *arg = (struct args *)input; int size = arg->size; for (int i = arg->start_row; i < arg->end_row; i++) { for (int j = 0; j < size; j++) { arg->array[i][j] = 0; } } return NULL; } int main() { int number; printf("please enter the size : "); scanf("%d", &number); // 分配线程参数结构体内存 struct args *arguments[2]; for (int i = 0; i < 2; i++) { arguments[i] = (struct args *)malloc(sizeof(struct args)); arguments[i]->size = number; } // 动态分配二维数组内存 int **array = (int **)malloc(number * sizeof(int *)); for (int i = 0; i < number; i++) { array[i] = (int *)malloc(number * sizeof(int)); } // 拆分任务区间:线程0处理前半行,线程1处理后半行 arguments[0]->array = array; arguments[0]->start_row = 0; arguments[0]->end_row = number / 2; arguments[1]->array = array; arguments[1]->start_row = number / 2; arguments[1]->end_row = number; pthread_t threads[2]; // 创建并启动线程 for (int i = 0; i < 2; i++) { pthread_create(&threads[i], NULL, fill, (void *)arguments[i]); } // 等待线程结束并释放参数内存 for (int i = 0; i < 2; i++) { pthread_join(threads[i], NULL); free(arguments[i]); } // 输出填充后的数组 for (int row = 0; row < number; ++row) { for (int col = 0; col < number; ++col) { printf("\t %d", array[row][col]); } printf("\n"); } // 释放二维数组内存 for (int i = 0; i < number; i++) { free(array[i]); } free(array); return 0; }
关键修改说明
- 结构体新增
start_row和end_row字段,让每个线程处理独立的行区间,避免多线程竞争,无需额外加锁。 - 将固定数组改为
int **array,在main中根据用户输入的number动态分配二维数组内存,完全适配任意合法输入尺寸。 - 线程函数仅处理分配给自己的行区间,操作无重叠,既保证线程安全,又提升了并行效率。
内容的提问来源于stack exchange,提问作者bedirates
相关产品推荐
相关产品推荐

