Joel Shevin
Joel Shevin

Reputation: 103

C Program exits without any output

This had a previous question regarding multi thread issues Here. Now the issue is that the program exits without any input. The program gets the input from a text file given as arguments with executing. It should only contain numbers separated by spaces and if theres any other character it should give an error as done in row_check functions. Can anyone suggest why it would exit without any error ?.

#include<pthread.h>
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<ncurses.h>
const unsigned int NUM_OF_THREADS = 9;
typedef struct thread_data_s {
char *ptr;
int row_num;
} thread_data_t;

void report(const char *s,int w,int q);

void* row_check(void* data)
{
    thread_data_t *my_data_ptr = data;
    int j, flag;

    flag=0x0000;

    for(j = 0; j < 9; j++)
{
    flag |= 1u << ( (my_data_ptr->ptr)[j] - 1 );

    if (flag != 0x01FF){
        report("row", my_data_ptr->row_num, j-1);
    }
}   

return NULL;
}

void report(const char *s,int w,int q)
{
   printf("\nThe sudoku is INCORRECT");
   printf("\nin %s. Row:%d,Column:%d",s,w+1,q+1);
   getchar();

   exit(0);
 }


 int main(int argc, char* argv[])
 {
     int i,j;
     char arr1[9][9];
     FILE *file = fopen(argv[1], "r");
     if (file == 0)
 {
    fprintf(stderr, "failed");
    exit(1);
 }
    int col=0,row=0;
    int num;

    while(fscanf(file, "%c ", &num) ==1) {
        arr1[row][col] = num;
        col++;

    if(col ==9)
    {
        row++;
        col = 0;
    }
 }

 fclose(file);

int n;

thread_data_t data[NUM_OF_THREADS];
pthread_t tid;
pthread_attr_t attr;


for(n=0; n < NUM_OF_THREADS; n++)
{
     data[n].ptr = &arr1[n][0];
     data[n].row_num = n;
     pthread_create(&tid, &attr, row_check, &data[n]);
}


for(n=0; n < NUM_OF_THREADS; n++)
{
     pthread_join(tid, NULL);
}


return 0;

}

Upvotes: 2

Views: 1219

Answers (2)

Myst
Myst

Reputation: 19221

The following in one of the issues in the code and it would explain why the application exists so soon...

The following code doesn't join all the threads it creates (so the application exits and terminates the threads before they finished running):

thread_data_t data[NUM_OF_THREADS];
pthread_t tid;
pthread_attr_t attr;

for(n=0; n < NUM_OF_THREADS; n++)
{
     data[n].ptr = &arr1[n][0];
     data[n].row_num = n;
     pthread_create(&tid, &attr, row_check, &data[n]);
}


for(n=0; n < NUM_OF_THREADS; n++)
{
     pthread_join(tid, NULL);
}

As you can see, the code is only saving the pointer to one of the threads (the value in tid is always replaced, overwriting the existing data) and joining that thread (instead of all of them).

This might be better constructed as:

thread_data_t data[NUM_OF_THREADS];
pthread_t tid[NUM_OF_THREADS];

for(n=0; n < NUM_OF_THREADS; n++)
{
     data[n].ptr = &arr1[n][0];
     data[n].row_num = n;
     pthread_create(tid + n, NULL, row_check, &data[n]);
}


for(n=0; n < NUM_OF_THREADS; n++)
{
     pthread_join(tid[n], NULL);
}

This way the application will wait for all the threads to complete their tasks (and report any errors) before returning.

Upvotes: 1

user3629249
user3629249

Reputation: 16540

Can anyone suggest why it would exit without any error ?.

Yes,

the posted code has no action when all 9 rows of the puzzle result are correct, it just gracefully exits.

and to further muddy the logic.

The posted code only checks the last thread created, and when that thread exits, the program exits, That does not mean the other threads have exited

One further serious detail. the call to pthread_create() is passing the address of the attr variable, but that variable contains what ever trash is/was on the stack where that variable was declared. Since the code is not setting any specific attributes for the threads, strongly suggest eliminate the variable and simply use NULL in the second parameter to pthread_create()

Upvotes: 1

Related Questions