C --(HW) Casting void pointer to struct

sweenish

Diamond Member
May 21, 2013
3,656
60
91
I have a C assignment that's about solving a word search. The specific errors I'm getting say that I'm "dereferencing pointer to incomplete type." This occurs when using the -> operator to access struct members.

I also have a warning about a for loop running two conditions, but it's just a warning, and not my own code. I really just want these errors fixed. Googling and StackOverflow almost got me there.

Two different programs were provided as references, and I was allowed to mash them together as I saw fit, so much of this code is not mine.

With that said, I think it's just about put together. I'm just having an issue with the function that my threads are supposed to run.

Since I'm only allowed to pass a single void pointer, I'm passing one to a specific struct in an array.

Here are what I think are the relevant bits, with the full code at the end.
struct definition and relevant function header, along with array I'm using:
Code:
typedef struct block_change_t
{
    int row_change;
    int col_change;
    char direction[4];
} Direction;
 
void search(void *param);


Direction coords[8] = {{-1, 0, "N"}, {-1, 1, "NE"}, {0, 1, "E"}, {1, 1, "SE"}, {1, 0, "S"}, {1, -1, "SW"}, {0, -1, "W"}, {-1, -1, "NW"}};
thread creation:
Code:
    pthread_create( thread+0, NULL, (void *)search, (void *) &coords[0]);     pthread_create( thread+1, NULL, (void *)search, (void *) &coords[1]);
    pthread_create( thread+2, NULL, (void *)search, (void *) &coords[2]);
    pthread_create( thread+3, NULL, (void *)search, (void *) &coords[3]);
    pthread_create( thread+4, NULL, (void *)search, (void *) &coords[4]);
    pthread_create( thread+5, NULL, (void *)search, (void *) &coords[5]);
    pthread_create( thread+6, NULL, (void *)search, (void *) &coords[6]);
    pthread_create( thread+7, NULL, (void *)search, (void *) &coords[7]);
Trying to get my struct back from the void *:
Code:
struct Direction *dir = param;
I think the issue lies in my attempt to convert the void pointer back to being a structure.
Commands like:
Code:
dir->row_change
don't work.

Here's the complete program:
Code:
#include <stdio.h>
#include <pthread.h>
#include <string.h>
 
#define SIZE 20
 
typedef struct block_change_t
{
    int row_change;
    int col_change;
    char direction[4];
} Direction;
 
void search(void *param);
 
char letters[SIZE + 2][SIZE + 2] = {{'\0'}};
char words[SIZE][SIZE] = {{'\0'}};
int count = 0;
 
 
int main (int argc, char *argv[])
{
    // Program must be invoked with parameters for file names
    if (argc < 3) {
        printf("Usage: <block-letter file> <words-file>");
        return -1;
    }
 
    // Variable Declaration
    FILE *fletters;
    FILE *fwords;
    int dimension;
    char trash;
    int i;
    int length;
    Direction coords[8] = {{-1, 0, "N"}, {-1, 1, "NE"}, {0, 1, "E"}, {1, 1, "SE"},
      {1, 0, "S"}, {1, -1, "SW"}, {0, -1, "W"}, {-1, -1, "NW"}};
    pthread_t thread[8];
 
    // Files are opened. There is no checking to see if the files were passed in the right order
    fletters = fopen(argv[1], "r");
    if (fletters == NULL) {
        printf("The file %s could not be opened for reading\n", argv[1]);
        return -1;
    }
 
    fwords = fopen(argv[2], "r");
    if (fwords == NULL) {
        printf("The file %s could not be opened for reading\n", argv[2]);
        fclose(fletters);          
        return -1;
    }
 
    fscanf(fletters, "%d", &dimension);
    fscanf(fletters, "%c", &trash); 
 
    if (dimension > SIZE)
    {
       printf("The input puzzle is too big for this program to handle");
       printf(" unless the SIZE value is changed!\n");
       return (1);
    }
    /* Read in the block array of letters by rows, starting with row 1
      of the two-dimensional array in memory. The first row and column
      will be left unchanged with their initial null character values. */
    i = 1;
    while (fgets(letters[i] + 1, SIZE + 1, fletters) != NULL)
    {
       length = strlen(letters[i]);  /* trim off the newline char */
       letters[i][length - 1] = '\0';
       i++;
    }
 
    /* Read the words to search for into the words array. */
    i = 0;
    while (fgets(words[i], SIZE, fwords) != NULL)
    {
       length = strlen(words[i]);  /* trim off the newline char */
       words[i][length - 1] = '\0';
       count++;
       i++;
    }
 
    pthread_create( thread+0, NULL, (void *)search, (void *) &coords[0]);
    pthread_create( thread+1, NULL, (void *)search, (void *) &coords[1]);
    pthread_create( thread+2, NULL, (void *)search, (void *) &coords[2]);
    pthread_create( thread+3, NULL, (void *)search, (void *) &coords[3]);
    pthread_create( thread+4, NULL, (void *)search, (void *) &coords[4]);
    pthread_create( thread+5, NULL, (void *)search, (void *) &coords[5]);
    pthread_create( thread+6, NULL, (void *)search, (void *) &coords[6]);
    pthread_create( thread+7, NULL, (void *)search, (void *) &coords[7]);
 
    pthread_join(thread[0], NULL);
    pthread_join(thread[1], NULL);
    pthread_join(thread[2], NULL);
    pthread_join(thread[3], NULL);
    pthread_join(thread[4], NULL);
 
    fclose(fletters);
    fclose(fwords);
    return 0;
}
 
 
void search(void *param)
{
   char buffer[SIZE + 1];  /* holds line of letters from the block array */
   int found = 0;          /* just starting */
   int k;                  /* will index into the words array */
   int row;                /* row loop index */
   int col;                /* column loop index */
   int r, c;               /* for copying letters from the block array into
                              the buffer for inspection */
   int i;                  /* corresponding position in the buffer */
   struct Direction *dir = param;
 
   /* Try each word of the list. */
   for (k = 0; k < count; k++)
   {
      found = 0;  /* not yet, anyway */
      /* Examine every position until found or search ends. */
      for (row = 1; !found && row <= SIZE; row++)
      {
         for (col = 1; !found && col <= SIZE; col++)
         {
            /* copy letters from the given position until a null is found. */
            i = 0;      /* set the buffer start position */

            // GETTING ERRORS IN THIS FOR LOOP DEFINITION
            for (r = row, c = col; letters[r][c] != '\0'; r += dir->row_change, c += dir->col_change) {  
               buffer[i++] = letters[r][c];
            }
 
            buffer[i] = '\0';
 
            if (strncmp(words[k], buffer, strlen(words[k])) == 0)
            {
               printf("%-10s %2d, %2d %s\n", words[k], row, col, dir->direction);
               found = 1;
            }
         }
      }
   }
}
compile command:
Code:
gcc -Wall -lpthread -o test [name_of_file.c]
As always, any help is greatly appreciated.
 
Last edited:

sm625

Diamond Member
May 6, 2011
8,172
137
106
Code:
struct Direction *dir;
dir = (struct block_change_t*) param;
 

sweenish

Diamond Member
May 21, 2013
3,656
60
91
The struct shouldn't be necessary since you used a typedef.
I tried taking the word struct out, which I swear I had tried already, but this time it took.

Code compiled error-free, and works as it should.

Thank you very much!