C语言数独验证器子网格线程参数传递错误排查求助
数独子网格线程验证器的参数传递错误排查与修复
看起来你遇到的核心问题是子网格参数数组的初始化索引错误,导致大部分数组元素未被正确赋值,再加上主线程没有等待子线程完成,才出现了打印混乱和线程输出不全的情况。咱们一步步拆解问题:
1. 子网格数组初始化的索引bug
你的初始化循环里,用i(步长3,取值0、3、6)作为subgridArray的索引,但内层j循环会执行3次,每次都覆盖同一个subgridArray[i]的列参数。比如:
- 当
i=0时,j从0→3→6,三次赋值后subgridArray[0]的列参数会被最后一次的j=6覆盖,变成leftColumn=6, rightColumn=8 - 而
subgridArray[1]、subgridArray[2]、subgridArray[4]等索引的元素完全没被初始化,内存里是随机垃圾值,这就是你第二次打印数组时出现乱码的原因。
修正方案:添加独立的数组索引计数器
改用一个单独的变量idx来遍历subgridArray的9个元素,确保每个位置都被正确赋值:
int main() { int i,j, idx = 0; // 直接用typedef后的类型声明数组,更清晰 indexParam subgridArray[9]; //Initialize subgrids for(i=0;i<9;i=i+3) { for(j=0;j<9;j=j+3) { subgridArray[idx].topRow = i; subgridArray[idx].bottomRow = i+2; subgridArray[idx].leftColumn = j; subgridArray[idx].rightColumn = j+2; printf("top row %d, bottom row %d, left col %d, right col %d \n", subgridArray[idx].topRow, subgridArray[idx].bottomRow, subgridArray[idx].leftColumn, subgridArray[idx].rightColumn); idx++; // 每次循环后索引+1,覆盖9个子网格 } } // 现在再遍历打印,所有元素都会是正确值 for(i=0;i<9;i++) { printf("Top row: %d, Bottom Row: %d, Left Column: %d, right Column: %d\n", subgridArray[i].topRow, subgridArray[i].bottomRow, subgridArray[i].leftColumn, subgridArray[i].rightColumn); } // ... 后续线程创建代码 }
2. 线程输出不全的问题
你说只打印了5个线程的信息,这是因为主线程没有等待子线程执行完毕就继续运行甚至退出了。主线程创建完线程后,会直接往下走(甚至结束进程),此时子线程可能还没来得及执行printf就被终止了。
修正方案:添加pthread_join等待所有子线程
在创建完所有子线程后,循环调用pthread_join等待每个线程完成:
//Create worker threads for subgrids pthread_t tid_Subgrid[9]; // 确保数组大小为9 for(i=0;i<9;i++) { int ret = pthread_create(&tid_Subgrid[i], NULL, subgridChecker, &(subgridArray[i])); if(ret != 0) { perror("pthread_create failed"); exit(EXIT_FAILURE); } printf("%d I am subgrid thread %lu: ,my bounds are: %d, %d, %d,%d\n", i, (unsigned long)tid_Subgrid[i], subgridArray[i].topRow,subgridArray[i].bottomRow, subgridArray[i].leftColumn, subgridArray[i].rightColumn); } // 等待所有子线程执行完成 for(i=0;i<9;i++) { pthread_join(tid_Subgrid[i], NULL); }
另外注意:pthread_t的打印要用%lu(无符号长整型),避免格式不匹配导致的输出错误。
3. 线程函数的参数解析
确保你的subgridChecker函数正确解析传入的参数,避免类型转换错误:
void* subgridChecker(void* arg) { // 安全地转换参数类型 indexParam* params = (indexParam*)arg; if(params == NULL) { fprintf(stderr, "Invalid parameter passed to thread\n"); return NULL; } // 这里添加你的子网格重复检查逻辑 printf("Subgrid thread %lu running with bounds: top=%d, bottom=%d, left=%d, right=%d\n", (unsigned long)pthread_self(), params->topRow, params->bottomRow, params->leftColumn, params->rightColumn); // 返回检查结果(比如用malloc分配一个int存储结果,主线程记得释放) int* result = malloc(sizeof(int)); *result = 1; // 1表示验证通过,0表示失败 return result; }
最后验证
修正后,你会发现:
- 数组遍历打印的所有子网格参数都是正确的
- 9个子线程都会完整输出自己的参数信息
- 子线程能拿到正确的网格边界,完成重复数字检查
内容的提问来源于stack exchange,提问作者Henry Gray
相关产品推荐
相关产品推荐

