I'm new to this whole C thing, but I keep getting this error with my code
UArray2.c:19:error: request for member ‘i’ in something not a structure or union
It's obviously the uarray.i in my main function, but I don't get why it isn't seeing it.
This is my .h file. Not too interesting...
//UArray2.h
#include <stdlib.h>
#include <stdio.h>
#ifndef UARRAY2_INCLUDED
#define UARRAY2_INCLUDED
#define T UArray2_T
typedef struct T *T;
#undef T
//#undef UARRAY2_INCLUDED //undef?
#endif
This is my .c file. Pretty simple stuff.
//UArray.c
#include <stdlib.h>
#include <stdio.h>
#include "UArray2.h"
#define T UArray2_T
struct T{
int i;
};
int main()
{
UArray2_T uarray;
uarray.i=0;
return 0;
}
#undef T
So, does anyone have any idea as to why I'm getting this compile error? It's likely something stupid that I did.
In the header file you have
typedef struct T *T;
This means that when you declare the variable uarray you are actually declaring a pointer. So you should initialize the i member as
uarray->i = 0;
This will however most likely crash, as the pointer is uninitialized and can point to any location in memory. Either allocate memory for the pointer
UArray2_T uarray = malloc(sizeof(*uarray));
Or make it point to another structure
struct UArray2_T real_uarray;
UArray2_T uarray = &real_uarray;
I think there is a problem with the initialization as you are using the pointer in the header file.
typedef struct T *T;
You are actually pointing to the memory location by declaring uarray.
Try to rectify this error.
Related
So I want to share a macro between different .c files which "returns" the "content" (which is a member of a struct) of a element of a matrix of structures. I have these files:
matrix.h:
#ifndef _MATRIX_H
#define _MATRIX_H
#include <stdio.h>
#include <stdlib.h>
typedef struct Matrix_Pos_Struct Matrix_Pos;
#define GET_CONTENT(i, j) (mz[(i)][(j)].content)
#endif
matrix.c:
#include "matrix.h"
extern Matrix_Pos** mz;
struct Matrix_Pos_Struct{
char content;
char visited;
};
And then I have another_file.c that invokes the macro GET_CONTENT(), and mz is a double pointer that is declared in yet another file where the main() is at. How can I make this while achieving the most abstraction possible? This is fora university project and the teacher values abstraction
I came to the conclusion that making a function is a better way of doing this, instead of a macro
I'm new to header files and am not sure why I am getting this error. The first piece of code is from the relevant header file, and gives the expected identifier error:
#define MAX_ADDR_LENGTH 1000
struct listNode{
char addr[MAX_ADDR_LENGTH];
struct listNode *next;
};
Related to this, there is another error in the file relevant to that header, which gives me a "note: in expansion of macro 'MAX_ADDR_LENGTH', which it gives me on the line which gives the declaration of int MAX_ADDR_LENGTH:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "header.h"
char *crawl(char* getLinksFrom, int hopTo){
int MAX_ADDR_LENGTH = 300;
char startAddr[MAX_ADDR_LENGTH];
char destAddr[MAX_ADDR_LENGTH];
}
I've tried a number of things hoping it was just a small oversight (removed the #define altogther, deleted the line that gives the int MAX_ADDR_LENGTH declaration, just deleted the phrase 'int' from the same; all of which just caused even more errors).
The problem: ‘MAX_ADDR_LENGTH’ is defined twice in your code; Once as a Macro and once as a variable.
Try to delete the statement declaring MAX_ADDR_LENGTH as a variable.
Build your header like this:
#ifndef HEADER_H
#define HEADER_H
#define MAX_ADDR_LENGTH 1000
typedef struct _listNode{
char addr[MAX_ADDR_LENGTH];
struct _listNode *next;
} listNode;
#endif /* HEADER_H */
and use it like this:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "header.h"
char *crawl(char* getLinksFrom, int hopTo){
char startAddr[MAX_ADDR_LENGTH];
char destAddr[MAX_ADDR_LENGTH];
.... more code
}
The #ifndef...#endif construct is called an include guard. It's not necessary to get your code compiled, but good practice to use it.
The typedef is used to define the node structure. It does not create a variable yet, it's just defining a type named listNode that you can use to build your list later on.
So, out of the blue, the compiler decides to spit this in face:
"field customer has incomplete type".
Here's the relevant snippets of code:
customer.c
#include <stdlib.h>
#include <string.h>
#include "customer.h"
struct CustomerStruct;
typedef struct CustomerStruct
{
char id[8];
char name[30];
char surname[30];
char address[100];
} Customer ;
/* Functions that deal with this struct here */
customer.h
A header file for customer.h
#include <stdlib.h>
#include <string.h>
#ifndef CUSTOMER_H
#define CUSTOMER_H
typedef struct CustomerStruct Customer;
/* Function prototypes here */
#endif
This is where my problem is:
customer_list.c
#include <stdlib.h>
#include <string.h>
#include "customer.h"
#include "customer_list.h"
#include "..\utils\utils.h"
struct CustomerNodeStruct;
typedef struct CustomerNodeStruct
{
Customer customer; /* Error Here*/
struct CustomerNodeStruct *next;
}CustomerNode;
struct CustomerListStruct;
typedef struct CustomerListStruct
{
CustomerNode *first;
CustomerNode *last;
}CustomerList;
/* Functions that deal with the CustomerList struct here */
This source file has a header file, customer_list.h ,but I don't think its relevant.
My Problem
In customer_list.c, at the line with the comment /* Error Here */, the compiler complains about field customer has incomplete type.
I've been googling this problem all day, and now im at the point of pulling out my eyeballs and blending them with strawberries.
What is the source of this error ?
Thanks in advance :)
[P.S. if I forgot to mention something, let me know. Its been a stressful day for me, as you might tell ]
Move the struct declaration to the header:
customer.h
typedef struct CustomerStruct
{
...
}
In C, the compiler needs to be able to figure out the size of any object that is referenced directly. The only way that the sizeof(CustomerNode) can be computed is for the definition of Customer to be available to the compiler when it is building customer_list.c.
The solution is to move the definition of the struct from customer.c to customer.h.
It seems that something like
typedef struct foo bar;
won't work without the definition in the header. But something like
typedef struct foo *baz;
will work, as long as you don't need to use baz->xxx in the header.
What you have is a forward declaration of Customer structure that you are trying to instantiate. This is not really allowed because compiler has no idea about the structure layout unless it sees it definition. So what you have to do is move your definition from the source file into a header.
I am trying to call a function in main.c from io.h that reads data from a file, stores that data into multiple structs, then somehow lets me pass the different structs as arguments in later functions in main. Those later functions will be defined in other files, such as alg.h.
How do I go about doing this? Do I use extern and make the structs global and put them in a separate file? Is it possible to have a function from alg.h have a return type of one of the structs? Does it depend on the order of my includes?
The code pasted below complies and works, but any attempt to move either of the structs causes the program to not compile.
Also, is it possible to have, for example, a struct declared in alg.h, then functions that have that struct as a parameter declared later in alg.h. Then in main.c, you initialize and pass the struct into a function declared in io.h, give the struct some values, have it returned to main.c, then pass that into the function declared in alg.h? I know that sounds like a class, but I need a C solution and I only need one instance of the struct floating around.
Thanks.
io.h
struct s1 {
int num1;
double num2;
};
struct s2 {
int num3;
double num4;
};
void io_init(struct s1*, struct s2*);
io.c
#include <stdio.h>
#include <stdlib.h>
#include "io.h"
void io_init(struct s1* s1i, struct s2* s2i)
{
s1i->num1 = 5;
s1i->num2 = 2.4;
FILE *fp;
char line[80];
fp = fopen("input.txt","rt");
fgets(line, 80, fp);
sscanf(line,"%i",&s2i->num3);
fgets(line, 80, fp);
sscanf(line,"%i",&s2i->num4);
fclose(fp);
}
alg.h
void ga_init(struct s1);
alg.c
#include <stdio.h>
#include "io.h"
#include "ga.h"
void ga_init(struct s1 s1i)
{
printf("%i", s1i.val1);
}
main.c:
#include <stdio.h>
#include "io.h"
#include "ga.h"
int main() {
struct s1 s1i;
struct s2 s2i;
io_init(&s1i, &s2i);
ga_init(s1i);
return 0;
}
Every file which requires the declaration of your types (i.e., wants to use them) must include your header file (ok, so forward declarations and pointers will work, but they can't be dereferenced without the definition and that's not really applicable here anyway.)
So, to elaborate, if file X needs to use struct Y then it needs to include the header file which contains its declaration, that's it.
/* X.c */
#include "Y.h" /* <-- that's it! */
void foo(Y *obj) {
/* ... */
}
Here is some advice.
Your .h file is not defining struct objects. It's just defining the type. It's fine the way it is. Everyone who touches any struct of those types should include this file.
It's very rare to need to pass a struct by value as you are doing in the call to ga_init. You will essentially always want to call by reference, like you did with io_init.
Yes, you can return a struct, but again, it would almost always be better to return a reference to a struct.
You can certainly share globally defined structs and you don't need extern unless your linker is something awful. But sharing a reference to a struct allocated in main() amounts to roughly the same thing.
I am new to C.This are the files and codes that I am working on. I am trying to call a function (refineMatch) implemented in a separate file from the main function. function refineMatch returns a struct. I am having problems in compiling the code which is related to accessing elements in the returned struct. The compile error occurs in main.c file. Code below shows where the error happens.
refine.h
#include <cv.h>
#include <cxcore.h>
#include <highgui.h>
struct matchingpair{
CvPoint p1, p2;
};
struct matchingpair_array{
struct matchingpair* elements;
int length;
};
struct matchingpair_array *refineMatch(struct matchingpair* pairs,int pointcount, int bestpair);
refine.c
#include "refine.h"
#include "utils.h"
#include <stdlib.h>
struct matchingpair_array *refineMatch(struct matchingpair* pairs,int pointcount, int bestpoint){
struct matchingpair_array refinedPairs;
refinedPairs.elements=malloc(incount*sizeof(struct matchingpair));
int *in=malloc(pointcount*sizeof(int)), i=0,incount=8;
// several statements - including filling in[] with data
for(i=0;i<incount;i++){
refinedPairs.elements[i]=pairs[in[i]];
fprintf(stderr,"%d\n",in[i]);
}
refinedPairs.length=incount;
free(in);
// several other free() operations non include refinedPairs or elements
return &refinedPairs;
}
main.c
#include "refine.h"
#include <stdio.h>
int main( int argc, char** argv ){
struct matchingpair* pairs;
int matchcount=0,bestpair;
pairs=(struct matchingpair*)malloc(pairArrSize*sizeof(struct matchingpair));
//values are assigned to pairs, matchcount and bestpair
struct matcingpair_array* result=(struct matcingpair_array*)refineMatch(pairs,matchcount,bestpair); /*(casting removed this warining)
warning: initialization from incompatible pointer type*/
fprintf(stderr,"%d \n",result->length); //error: dereferencing pointer to incomplete type
//some other code
}
Please explain me what I am doing wrong here. I am using gcc.
Thank you.
refineMatch() does not return a struct. It returns a pointer to a struct matchingpair_array.
and matcingpair_array is not the same as mathcingpair_array: it is missing an h