I haven't been writing C for very long, and so I'm not sure about how I should go about doing these sorts of recursive things... I would like each cell to contain another cell, but I get an error along the lines of "field 'child' has incomplete type". What's up?
typedef struct Cell {
int isParent;
Cell child;
} Cell;
Clearly a Cell cannot contain another Cell as it becomes a never-ending recursion.
However a Cell CAN contain a pointer to another Cell.
typedef struct Cell {
bool isParent;
struct Cell* child;
} Cell;
In C, you cannot reference the typedef that you're creating withing the structure itself. You have to use the structure name, as in the following test program:
#include <stdio.h>
#include <stdlib.h>
typedef struct Cell {
int cellSeq;
struct Cell* next; /* 'tCell *next' will not work here */
} tCell;
int main(void) {
int i;
tCell *curr;
tCell *first;
tCell *last;
/* Construct linked list, 100 down to 80. */
first = malloc (sizeof (tCell));
last = first;
first->cellSeq = 100;
first->next = NULL;
for (i = 0; i < 20; i++) {
curr = malloc (sizeof (tCell));
curr->cellSeq = last->cellSeq - 1;
curr->next = NULL;
last->next = curr;
last = curr;
}
/* Walk the list, printing sequence numbers. */
curr = first;
while (curr != NULL) {
printf ("Sequence = %d\n", curr->cellSeq);
curr = curr->next;
}
return 0;
}
Although it's probably a lot more complicated than this in the standard, you can think of it as the compiler knowing about struct Cell on the first line of the typedef but not knowing about tCell until the last line :-) That's how I remember that rule.
From the theoretical point of view, Languages can only support self-referential structures not self-inclusive structures.
There is sort of a way around this:
struct Cell {
bool isParent;
struct Cell* child;
};
struct Cell;
typedef struct Cell Cell;
If you declare it like this, it properly tells the compiler that struct Cell and plain-ol'-cell are the same. So you can use Cell just like normal. Still have to use struct Cell inside of the initial declaration itself though.
I know this post is old, however, to get the effect you are looking for, you may want to try the following:
#define TAKE_ADVANTAGE
/* Forward declaration of "struct Cell" as type Cell. */
typedef struct Cell Cell;
#ifdef TAKE_ADVANTAGE
/*
Define Cell structure taking advantage of forward declaration.
*/
struct Cell
{
int isParent;
Cell *child;
};
#else
/*
Or...you could define it as other posters have mentioned without taking
advantage of the forward declaration.
*/
struct Cell
{
int isParent;
struct Cell *child;
};
#endif
/*
Some code here...
*/
/* Use the Cell type. */
Cell newCell;
In either of the two cases mentioned in the code fragment above, you MUST declare your child Cell structure as a pointer. If you do not, then you will get the "field 'child' has incomplete type" error. The reason is that "struct Cell" must be defined in order for the compiler to know how much space to allocate when it is used.
If you attempt to use "struct Cell" inside the definition of "struct Cell", then the compiler cannot yet know how much space "struct Cell" is supposed to take. However, the compiler already knows how much space a pointer takes, and (with the forward declaration) it knows that "Cell" is a type of "struct Cell" (although it doesn't yet know how big a "struct Cell" is). So, the compiler can define a "Cell *" within the struct that is being defined.
Another convenient method is to pre-typedef the structure with,structure tag as:
//declare new type 'Node', as same as struct tag
typedef struct Node Node;
//struct with structure tag 'Node'
struct Node
{
int data;
//pointer to structure with custom type as same as struct tag
Node *nextNode;
};
//another pointer of custom type 'Node', same as struct tag
Node *node;
Lets go through basic definition of typedef. typedef use to define an alias to an existing data type either it is user defined or inbuilt.
typedef <data_type> <alias>;
for example
typedef int scores;
scores team1 = 99;
Confusion here is with the self referential structure, due to a member of same data type which is not define earlier. So In standard way you can write your code as :-
//View 1
typedef struct{ bool isParent; struct Cell* child;} Cell;
//View 2
typedef struct{
bool isParent;
struct Cell* child;
} Cell;
//Other Available ways, define stucture and create typedef
struct Cell {
bool isParent;
struct Cell* child;
};
typedef struct Cell Cell;
But last option increase some extra lines and words with usually we don't want to do (we are so lazy you know ;) ) . So prefer View 2.
A Structure which contain a reference to itself. A common occurrence of this in a structure which describes a node for a link list. Each node needs a reference to the next node in the chain.
struct node
{
int data;
struct node *next; // <-self reference
};
All previous answers are great , i just thought to give an insight on why a structure can't contain an instance of its own type (not a reference).
its very important to note that structures are 'value' types i.e they contain the actual value, so when you declare a structure the compiler has to decide how much memory to allocate to an instance of it, so it goes through all its members and adds up their memory to figure out the over all memory of the struct, but if the compiler found an instance of the same struct inside then this is a paradox (i.e in order to know how much memory struct A takes you have to decide how much memory struct A takes !).
But reference types are different, if a struct 'A' contains a 'reference' to an instance of its own type, although we don't know yet how much memory is allocated to it, we know how much memory is allocated to a memory address (i.e the reference).
HTH
Related
i tryied to write the hashtable and found this github repository: enter link description here. I'm having difficulty understanding this code:
struct entry_s
{
char* key;
char* value;
struct entry_s* next;
};
typedef struct entry_s entry_t;
struct hashtable_s
{
int size;
struct entry_s** table;
};
typedef struct hashtable_s hashtable_t;
I've two questions:
Why there using the typedef struct entry_s entry_t; instead of
struct entry_s
{
char* key;
char* value;
struct entry_s* next;
}entry_t;
because if i use second way i will have error.
What does that code mean: struct entry_s** table;
I know this question can be so eazy to answer, but I will be glad if you help me
Why there using typedef struct entry_s entry_t; instead of
struct entry_s
{
char* key;
char* value;
struct entry_s* next;
};entry_t;
The syntax you give is not correct and does not do what you think. The last line, };entry_t;, is regarded as a new statement, because your compiler expects that after each ; there will be a new one. What you want to write is the following code:
struct entry_s
{
char* key;
char* value;
struct entry_s* next;
} entry_t;
This structure is a linked list, you can see that one of the fields (the last one) uses the same structure to keep a data. In a more abstract way, you can see this code such as:
struct my_linked_list_s
{
T data;
struct my_linked_list_s *next;
};
In C, a recursive data type (i.e. one that is used in its own definition), requires a pointer (for reasons of measuring the size of the structure*), which is why we see one in the next field. Then, in order to distinguish between the "internal" use of the structure and its external use, we define an alias type:
typedef struct my_linked_list_s my_linked_list_t;
Or, in your case:
typedef struct entry_s entry_t;
This is not a necessary thing though, but your implementation has chosen to do so. You can see the naming convention: _s for "structure" and _t for "type".
Because if i use second way i will have error.
You should read your compiler's error messages more carefully, it would have helped you understand what's wrong.
What does that code mean: struct entry_s** table;
This is an array of pointers. Your implementation has chosen to use linked lists and pointers, this function clearly describes the adding part.
For a better overview of the C hash tables, check out this answer.
*To determine the size of a structure (sizeof(struct my_struct)), the sum of the size of all fields is used. If we were to determine the size of a recursive structure without using a pointer (a pointer has a fixed size, for any type of data), then the structure would have an infinite size. To avoid this problem, we therefore use a pointer.
The answer for the second question is you are decalring an array of pointer that can store the pointers of the type struct entry_s** .
First time asking a question but I did look around Google and stackoverflow to see if someone has asked something similar before. In malloc, recasting and free, it looked like the OP asked something similar for example. But it was more complicated.
I was wondering whether it's possible to create a generic function for a list structure in C that traverses the list given that you know that the different types of structures will always have a "next" field.
For example, given these two list-type structures:
typedef struct _list1 {
int value;
list1 *next;
} list1;
typedef struct _list2 {
int value;
char *string;
list2 *next;
} list2;
Is it possible to create a generic void freeList((void *) list) function or something which looks something like the below? I am aware it's a simple thing to write both free functions for each individual list separately.
void freeList((void *) list) {
// Included this because the structs would have different sizes
// so I thought it would be possible to cast it in order to properly dereference the field.
if (sizeof *list == sizeof list1)
*list = (list1) list;
else if (sizeof *list == sizeof list2)
*list = (list2) list;
if (!list) return;
else {
free(list->next);
free(list);
}
}
So far, my experiments with the code shown above didn't fare well given that gcc would complain about dereferencing a void * pointer.
Making a heterogeneous list can be achieved by the use of a tagged union, or just a tag and casting:
struct list_item {
struct list_item *next;
enum datatype type;
void *contents;
};
or
struct list_item {
struct list_item *next;
enum datatype type;
union {
int some_int;
char some_char;
} contents;
};
Then while traversing the list you just have to verify the type stored in type before using the contents of the element.
This check:
if (sizeof *list == sizeof list1)
*list = (list1) list;
else if (sizeof *list == sizeof list2)
*list = (list2) list;
doesn't work because sizeof is a static construct: its value is defined at compilation time. You're just asking for the sizeof void.
is it possible to create a generic function for a list structure in C that traverses the list given that you know that the different types of structures will always have a "next" field.
Yes, as mentioned before; you must be careful that every structure starts with the "next" field; the two structures in your post should therefore be reordered like this:
typedef struct _list1 {
list1 *next;
int value;
} list1;
typedef struct _list2 {
list2 *next;
int value;
char *string;
} list2;
It is not clean code, because the compiler could reorder (and pad) the fields of the structure, but in general it should work.
Is it possible to create a generic void freeList((void) *list) function or something which looks something like...
This is possible if your structs do not refer malloced memory; or they do, but in a uniform (and known) way (note the first case is a sub-case of this last).
If the structs contain pointers pointing to memory that has to be freed, in fact, while freeing the struct the freeList() function should also free the referenced memory. A few solutions come to my mind:
1 - If all the different structs contain the same "pointers" layout, the routine can free those pointers in a uniform manner, knowing in advance what to do. In such scenario, one can also use pointer fields that are not used by all the structs, but only some.
2 - Every single instance of a struct could contain some helper field describing the pointer's layout. For example, just after the "next" field, another "mempntcnt" field could tell how many pointers (to be freed) follow the "next" field. Or, this "mempntcnt" could be passed as a parameter to freeList().
3 - This problem could be managed by a totally separated mechanism, outside the scope of freeList(). Much depends on the final usage: I mean, for a given (kind of) linked list, first call a routine that frees all the memory referenced by the list itself, then free the list by calling the common freeList(). After all, if different structs are needed, then different routines are used on them...
I hope I've been clear enough...
If you ensure that the next pointer is the first member of the struct then this is possible.
typedef struct list1 {
// next pointer must be first
struct list1 *next;
int value;
} list1;
typedef struct list2 {
// next pointer must be first
struct list2 *next;
int value;
char *string;
} list2;
void freeList(void *list) {
if (list) {
freeList(*(void**)list);
free(list);
}
}
I'm new to structures in c, I've been researching the difference between the . operator, and the -> operator. But I can't seem the find resources that explain what I want to know. So, why if I make structure without typedef, can I use it directly such as "header.first = x", and not having to say "struct header varName"? Also, what is the difference between the . and -> in this example, because it seems in this case I can use them interchangeably.
#include <stdio.h>
#include <stdlib.h>
typedef struct node{
int data;
struct node* next;
}node;
struct header{
int count;
node *first;
}header;
int main()
{
node *curptr = (node*)malloc(sizeof(node));
printf("%p\n",curptr);
header.first = curptr;
printf("%p\n",header.first);
header.count = 10;
printf("%i\n\n\n",header.count);
node* current = (node*)malloc(sizeof(node));
current->data = 5;
current->next = NULL;
printf("%i\n",current->data);
printf("%p",current);
}
struct header { ... } header; is simultaneously creating the struct type (struct header) as well as creating a global variable (named header, of type struct header). It is equivalent to doing:
struct header { ... };
struct header header;
When you write header.first = x, what you're doing is just modifying the global object named header.
typedef struct node { ... } node; is simultaneously creating the struct type (struct node) as well as a typedef to it (node). It is equivalent to doing:
struct node { ... };
typedef struct node node;
As for . vs ->: a->b is equivalent to (*a).b. It's just syntactic sugar.
struct in c is a place in memory which is big enough to keep data for all its fields. As with any other objects in 'c' you have a choice to use it as a variable or use a pointer to it. A pointer is essentially a memory address of this variable.
Also, every variable in 'c' has a type. The latter behaves like a template for creating variables and check their usage.
So, in the following example you create a struct type struct header and describe what it contains.
struct header{
int count;
node *first;
};
Now, using the type, you can create the variable named my_header:
struct header my_header;
or, as in your example, variable header.
struct header header;
As in you example you can combine both into a single statement.
Now, if you created a variable of type 'struct header', you can access its members using the . operator. The following operator will cause 'c' to access member count of your struct variable. It will calculate correct place in memory to put '10' into it.
header.count = 10;
as for pointers, you can create a variable which will keep an address to your object. In 'c' it needs to know what type of object it points to. So, the pointer ptr in the following example is assigned address & of the variable header.
struct header *ptr = &header;
Now you can use the pointer to access fields in the header, but it requires a different syntax ->. so, the following statement will be equivalent to the previous one:
ptr->count = 10;
Note that in both cases '10' was assigned to absolutely the same object, field of the variable 'header'.
Also to make life easier ant to stop typing struct every time, you can use the typedef operator to declare a named type, i.e.
typedef struct node myNodeType;
typedef struct node node;
now you have to 'named' types: myNodeType and node which are the same. you can use them to declare variables and pointers:
myNodeType var1; // variable
node *next; // pointer.
and as in case with variable declaration, you can combine it with struct declaration as in your example.
And malloc just allocates a chunk of dynamic memory and returns its address, aka pointer to it. so, node* current = (node*)malloc(sizeof(node)); just assigns address of allocated memory to the pointer current.
Hope it helps a bit.
I've tried and distill the following code as much as possible:
#include <stdlib.h>
typedef struct item{
struct item *next;
}item;
void addItem(item *list)
{
item *newItem = list;
while(newItem->next != NULL){
newItem = newItem->next;
}
newItem->next = malloc(sizeof(item));
newItem->next->next = NULL;
}
int main()
{
item *groceryList = NULL;
groceryList = malloc(sizeof(item));
if(groceryList == NULL)
return 1;
groceryList->next = NULL;
addItem(groceryList);
return 0;
}
This compiles fine. But changing the struct declaration to (or any combination of the changes):
typedef struct{ /*Removed "item"*/
item *next; /*Removed "struct"*/
}item;
Causes the following errors when compiling:
structpointertest.c:11:11: warning: assignment from incompatible pointer type
structpointertest.c:15:15: error: request for member 'next' in something not a structure or union
I don't understand what in the struct declaration is causing this issue? Does it have something to do with the fact I'm using a nested struct?
Thanks.
In C you must declare things before you can use them. When you do
typedef struct item { ... }
the struct item part is a declaration telling the compiler that there exists a structure name item. That means you could use it later, even inside the structure to define a pointer to itself.
When you do
typedef struct { ... } item;
you are not giving the structure a name, and the type-alias item is declared after the structure, so it can't be used inside the structure.
The simple solution is to use the first way. Another solution is to declare the type-alias before the structure, like
typedef struct item item;
struct item
{
item *next; // Can use type-alias, as it has been declared up above
};
Either way, you must still give the structure itself a name.
Also note that struct item *next; (or item *next;) declares a member variable that is a pointer to the structure, it's not the actual structure itself nested recursively. Creating a pointer to something that haven't been fully defined yet is okay.
I'm trying to program a network in C. I have nodes which are linked to each other and I 'd like to do that by making the struct member point to another member (not to another node, because I want to preserve the identity of the links).
The code I made to do that is something like:
struct node{
int k; //number of links
struct node.link **link; //<- wrong
};
but this is not right as node is not a variable but a type of variable (this is already discussed as an error in another QA: first you have to define a variable of node type and then apply the .link, but this doesn't help here). There's also a QA called "Struct member point at another struct member" but they don't do it from definition and it is not so clear how to generalize it (at least for me).
Is it a correct way to do this?
The problem is that the C language doesn't let you create the type you want. You need a type T with the property *T has the same type as T. You can't do that. (Well, function pointers have that property, but that's an irrelevant technicality.)
You have to introduce a new name. C only lets you do this with structs or similar constructions.
struct link {
struct link *ptr;
};
struct node {
int k;
struct link *link;
};
This will get you what you want. Now, in order to go from a struct link * to a struct node *, you'll have to do some pointer math:
struct node *node_from_link(struct link *link) {
return (struct node *) ((char *) link - offsetof(struct node, link));
}
This is also provided by the container_of macro, which is not part of the C standard, but you can find a definition for it online.
Or, you could just go the traditional route.
// Usually easier to do it this way...
struct node {
int k;
struct node *link;
};
Is this what you are after?
struct Node
{
int k; //number of links
void* link;
};
struct Node* create()
{
struct Node* node = malloc(sizeof(struct Node));
node->k = 0;
node->link = 0;
return node;
}
void link(struct Node* from, struct Node* to)
{
from->link = &(to->link);
}
int main()
{
struct Node* child = create();
struct Node* parent = create();
link(parent, child);
return 0;
}
I've used void* for the link for the reason expressed by Dietrich: you want a pointer to the link to be the same type as the link. This effectively means a cast, so why not just use a generic pointer?
Membership in a structure, generalized or specific, is not an attribute of C data types. There is therefore no way to declare a pointer that can only point to a structure member, and not to any other variable of compatible type.
On the other hand, you don't need to do anything special to declare a pointer that can point to a member of another structure. You just need a pointer to that member's data type, and structure membership is irrelevant to that data type.
For example, you can have
struct node {
int k; /* number of links */
struct node **links; /* points to a dynamic array of node pointers */
struct node **one_link; /* points to a node pointer from another node */
};
In that case, it might make sense to do something like this:
struct node *n1 = /* ... */;
struct node *n2 = /* ... */;
n2->one_link = &(n1->links[3]);
Overall, though, I think this is kind of convoluted. There is probably a better way to structure your data.
Update:
Based on your description of what you're after:
[...] links are bidirectional, if I destroy one link (say the one that links node 1 to node 3) I'll need to destroy the node 1 link AND the corresponding link from node 3. Then I need to know more than just who is link to who. I need to know which link they are using.
there are at least two possible solutions, depending on details of how your nodes are structured. If they are structured like I show above, with an array (dynamic or not) of pointers to other nodes, then your general idea simply won't work. That's because the position of each link within an array of links will change as you delete other links (supposing that you close the gaps). Instead, you can just scan:
struct node {
int k; /* number of links */
struct node **links; /* points to a dynamic array of node pointers */
struct node *parent; /* points to a node that links to this one */
};
void delete_node(struct node *n) {
if (n->parent) {
int i;
for (i = 0; i < n->parent->k; i += 1) {
if (n->parent->links[i] == n) {
/* ... delete the ith element of n->parent->links ... */
break;
}
}
}
/* ... clean up node n ... */
}
If one node's links to others are stored in separate members, on the other hand, then you could indeed provide a double-pointer by which to remove links from the parent, but the presence of member k in your original structure tells me that's not your situation.
Ok, this is how I finally solved it in my program:
typedef struct node{
int k; //connectivity
struct link **enlace; //vector of LINKs
}NODE;
typedef struct link{
NODE *node1;
NODE *node2;
}LINK;
Basicly, I defined two structures: one is the NODE type, which contains the information of how connected is the node and a vector of LINKs, and the other is the structure LINK which contains the information of the link itself, I mean which nodes the link connects.
With these two I'm able to create the network of nodes with a connectivity following a Poisson distribution, and then destroy each link one by one, choosing one link at random from a list and then redirecting the pointers of each node to NULL.