我正在try 在C上创建一个数独验证器作为多线程示例,其中3个并发线程判断数独中的行、列和网格,并判断数独是否有效,但我似乎每次运行它都会遇到分段错误.
#include <stdio.h>
#include <pthread.h>
#include <stdbool.h>
#include <unistd.h>
#include <math.h>
#include <stdlib.h>
#include <time.h>
#define MAX_ROWS_COLS 100
int rows;
int cols;
typedef struct {
int (*array)[MAX_ROWS_COLS];
int rows;
int cols;
} ThreadArgs;
bool checkRows(void* arg){
ThreadArgs* threadArgs = (ThreadArgs*)arg;
int (*array)[threadArgs->cols] = threadArgs->array;
int rows = threadArgs->rows;
int cols = threadArgs->cols;
bool used[rows];
for(int i = 0; i < rows; i++){
used[i] = false;
}
for(int i = 0; i < rows; i++){
for(int j = 0; j < cols; j++){
int num = array[i][j];
if(num < 1 || num > rows || used[num-1]){
return false;
}
used[num-1] = true;
}
for(int k = 0 ; k < rows; k++){
used[k] = false;
}
}
return true;
}
bool checkCols(void* arg){
ThreadArgs* threadArgs = (ThreadArgs*)arg;
int (*array)[threadArgs->cols] = threadArgs->array;
int rows = threadArgs->rows;
int cols = threadArgs->cols;
bool used[rows];
for(int i = 0; i < rows; i++){
used[i] = false;
}
for(int i = 0; i < rows; i++){
for(int j = 0; j < cols; j++){
int num = array[j][i];
if(num < 1 || num > rows || used[num-1]){
return false;
}
used[num-1] = true;
}
for(int k = 0 ; k < rows; k++){
used[k] = false;
}
}
return true;
}
int checkGrid(void* arg){
ThreadArgs* threadArgs = (ThreadArgs*)arg;
int (*array)[threadArgs->cols] = threadArgs->array;
int rows = threadArgs->rows;
int cols = threadArgs->cols;
bool used[rows];
for(int i = 0; i < rows; i++){
used[i] = false;
}
//Check grid
int grid = sqrt(rows);
int count = 0;
for(int i = 0; i < rows; i=i+grid){
for(int j = 0; j < rows; j = j+grid){
for(int k = 0; k < grid; k++){
for(int l = 0; l < grid; l++){
//printf("%d,%d\n",i+k,j+l);
int num = array[i+k][j+l];
if(num < 1 || num > rows || used[num-1]){
return false;
}
used[num-1] = true;
}
for(int m = 0; m < rows; m++){
used[m] = false;
}
}
}
}
return true;
}
bool checkSudoku(int array[rows][cols]){
pthread_t p1,p2,p3;
int rowResult, colResult, gridResult;
ThreadArgs args = {array, rows, cols};
pthread_create(&p1, NULL, checkRows, (void*)&args);
pthread_create(&p2, NULL, checkCols, (void*)&args);
pthread_create(&p3, NULL, checkGrid, (void*)&args);
pthread_join(p1, (void**)&rowResult);
pthread_join(p2, (void**)&colResult);
pthread_join(p3, (void**)&gridResult);
if(rowResult == 0 || colResult == 0 || gridResult == 0){
return false;
}
return true;
}
int main() {
clock_t start, end;
double cpu_time_used;
start = clock();
FILE *file;
char line[1000];
// Open the LaTeX file
file = fopen("input.tex", "r");
if (file == NULL) {
printf("Error opening file.\n");
return 1;
}
if (fgets(line, sizeof(line), file)) {
sscanf(line, "%d %d", &rows, &cols);
} else {
printf("Error reading dimensions.\n");
fclose(file);
return 1;
}
int **array = (int **)malloc(rows * sizeof(int *));
if (array == NULL) {
printf("Error allocating memory for array.\n");
return 1;
}
for (int i = 0; i < rows; i++) {
array[i] = (int *)malloc(cols * sizeof(int));
if (array[i] == NULL) {
printf("Error allocating memory for array.\n");
return 1;
}
}
for (int i = 0; i < rows; i++) {
if (fgets(line, sizeof(line), file)) {
char *token = strtok(line, " ");
for (int j = 0; j < cols && token != NULL; j++) {
array[i][j] = atoi(token);
token = strtok(NULL, " ");
}
} else {
printf("Error reading array values.\n");
fclose(file);
return 1;
}
}
fclose(file);
printf("Populated 2D array:\n");
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
printf("%d ", array[i][j]);
}
printf("\n");
}
if(checkSudoku(array)){
printf("Sudoku valid\n");
} else {
printf("Invalid\n");
}
end = clock();
cpu_time_used = ((double) (end - start)) / CLOCKS_PER_SEC;
double microseconds = cpu_time_used * 1000000;
printf("Execution time: %.2f microseconds\n", microseconds);
// Free dynamically allocated memory
for (int i = 0; i < rows; i++) {
free(array[i]);
}
free(array);
return 0;
}
如果重要的话,我在Kali Linux VM上运行这个,分配了4个线程.
它应该等待3个线程终止,然后在数独有效的情况下返回.