C: "misuse of undefined type pointers" struct X & deeferencing pointer to uncomplete type "

I considered similar questions for my couple of days, but still have not found a solution. Thanks for any help:

I have two files, one of which contains methods for working with rational numbers and one that processes them in a two-dimensional array. My problem is that matrix.c does not recognize the fraction structure contained in the .c fraction. I believe that my problem is somehow related to the way I declared my 2d array.

In fraction.c:

struct fraction { int integer; int num; int den; }; typedef struct fraction* fractionRef; //This line is in fraction.h 

In matrix.c:

 #include "fraction.h" typedef struct matrix* matrixRef; struct matrix { int rows; int columns; fractionRef *m; }matrix; matrixRef new_matrix ( int rows, int columns ) { matrixRef matrix; matrix = (matrixRef)malloc( sizeof( matrix ) ); matrix->m = (fractionRef*)calloc( rows, sizeof( fractionRef ) ); int i; for ( i=0; i<=rows; i++ ) matrix->m[i] = (fractionRef)calloc( columns, sizeof( fractionRef ) ); assert( matrix->m ); return matrix; } void free_matrix ( matrixRef freeMe ) { if ( freeMe != NULL ){ int i, j; for( i = 0; i <= freeMe->rows; i++ ){ for ( j = 0; j <= freeMe->columns; j++ ){ free_fraction( freeMe->m[i][j] ); //ERROR OCCURS HERE } } freeMe->rows = 0; freeMe->columns = 0; free(freeMe); freeMe = NULL; } } 

The error I am getting matches the row in matrix.c I am flagged.

 matrix.c:47: error: invalid use of undefined type 'struct fraction' matrix.c:47: error: dereferencing pointer to incomplete type 

This is probably all because I learned java BEFORE C, a big mistake !!! Thanks again for any help.

EDIT: Thanks to everyone. So now I see it all in the header .h files are similar to public in java. The definition of my fractional structure was not "publicly available" for the c compiler, so my .c matrix was not able to access it.

+4
source share
5 answers

You must move the definition of struct to the file fraction.h . Unlike Java, the compiler and linker do not β€œmagically” cause one .c file to reference information inside another .c file. (This can be done if you #include one .c file in another is a bad idea.)

Directive

#include "fraction.h"

forces the text content of the header file to be placed, as if cut-paste, in a line with this directive. The compiler processes one input file at a time, reading in the #include 'd files, and all the necessary information should be present while one .c file is compiled.

To help with your understanding, I will point out a terrible way to accomplish what you need: just cut and paste the definition of the struct fraction structure at the beginning of matrix.c , just before #include "fraction.h" - - the result will be compiled. In Java, the compiler may complain that you declared some duplicate types. In C, you created two different structures that have the same memory layout and the same name. To ensure their interchangeability in terms of linking object files, only the same memory layout is required.

Yes, this is a misunderstanding that you have chosen from Java. It’s great that you are learning C!

+10
source

Move the definition of struct fraction to "fraction.h" and

 #include "fraction.h" 

both in "fraction.c" and in "matrix.c"

+6
source

It's hard to guess your intentions, but I guess you need to pass a pointer to free_fraction.

 free_fraction( &(freeMe->m[i][j]) ); 
+3
source

At the same time, you can also change your definitions.

It’s better that you understand what is going on:

 struct fraction { int integer; int num; int den; }; typedef struct fraction fractionType; // We can now use fractionType and it'll be struct fraction typedef fractionType * fractionTypePtr; // We can now use fractionTypePtr and it will be a pointer to a fractionType which is a struct fraction 
+2
source

Alternatively, if you want to completely hide the implementation of the fraction structure, you can have fraction.h in the file:

 typedef struct fraction* fractionRef; 

and the actual declaration of your structure fraction in the fraction.c file.

However, since you are hiding the implementation, you must also define a function for all actions that you can perform on the fractional part, for example, get the value of the numerator and denominator, i.e. write things like:

 get_numerator(f); 

instead:

 f->num; 
0
source

All Articles